Theo nghĩa chung, xác thực tự đặt mình là rào cản đối với nhiều người khi họ đang cố gắng bắt đầu với một khuôn khổ cụ thể và Next.js không phải là ngoại lệ.
Mặc dù vậy, có rất nhiều tài nguyên xung quanh việc xây dựng các ứng dụng được xác thực bằng Next.js. Vâng, thậm chí còn có một dự án nguồn mở thực sự xử lý xác thực từ đầu.
Nhưng phạm vi của bài viết này không xoay quanh toàn bộ khái niệm xác thực. Chúng tôi chỉ chọn một mẫu cụ thể của quy trình xác thực: luồng "đặt lại mật khẩu" và cách triển khai luồng này ở phía máy khách — giao diện người dùng — của ứng dụng web.
Trong bài viết này, bạn sẽ thấy cách triển khai tính năng này bằng cách sử dụng công cụ truy xuất dữ liệu phổ biến, Axios — tính năng định tuyến động tích hợp sẵn của Next.js và hook
Có một câu nói phổ biến như sau: "Người dùng sẽ luôn quên mật khẩu của họ" và đó là sự thật tuyệt đối. Nhiều người thậm chí còn sợ trang "đặt lại mật khẩu" vì, nghĩ lại thì, sau khi dành nhiều thời gian cố gắng đoán mật khẩu của mình — tất cả đều vô ích — họ cảm thấy thất vọng hoặc tức giận khi truy cập vào trang cụ thể này.
Khi chúng ta tạo giao diện người dùng, chúng ta cũng nên cố gắng hết sức để làm cho trải nghiệm trở nên thú vị đối với người dùng. Mặc dù chúng ta rất muốn vượt qua quy trình đặt lại mật khẩu, nhưng UX của quy trình đó cũng nên được ưu tiên.
Có thể thấy quy trình chung của quy trình đặt lại mật khẩu như bên dưới.
Lệnh trên thực hiện việc đó cho chúng ta. Nhóm Next.js đã gửi một bản cập nhật mới cho khuôn khổ và họ cũng đã giới thiệu một số thư mục và tính năng mới trong cấu trúc dự án mặc định. Tuy nhiên, chúng tôi sẽ không đề cập nhiều đến khía cạnh đó vì nó nằm ngoài phạm vi của bài viết này. Bạn có thể đọc thêm về các bản cập nhật tại đây nếu bạn muốn.
Trong đoạn trích bên dưới, bạn sẽ thấy cấu trúc cơ bản của các tệp mà chúng ta sẽ tương tác trong bài viết này.
Ở trên, bạn sẽ thấy rằng các tệp trong cấu trúc thư mục khá nhỏ. Đó là vì tôi muốn trình bày ngắn gọn nhất có thể trong bài viết này.
Và vì việc triển khai luồng "đặt lại mật khẩu" là mối quan tâm hàng đầu của chúng tôi, tôi nghĩ tốt nhất là chúng ta nên hạn chế sự lộn xộn. Bây giờ, chúng ta hãy hiểu một chút về cấu trúc này.
Bạn sẽ thấy rằng chúng ta có thư mục
Các thư mục và tệp được đặt tên như thế này được gọi là các tuyến động và vì chúng nằm trong thư mục
Mẫu đặt tên tệp này thường được thấy khi bạn quyết định xây dựng một blog hoặc khi bạn tương tác với dữ liệu thay đổi dựa trên loại người dùng đã đăng nhập vào ứng dụng. Bạn có thể xem cách tôi sử dụng tính năng này của Next.js khi tôi xây dựng blog của mình. Bạn cũng có thể tìm hiểu thêm về tính năng này trong tài liệu Next.js.
Trong thư mục
Vì đây là tuyến động, nên các tham số URL
Bây giờ, chúng ta hãy cùng xem cách đọc tham số URL từ các tuyến động bằng hook
Đoạn trích trên cho thấy cách sử dụng cơ bản của hook. Vì chúng ta quan tâm đến các tham số truy vấn của URL, tốt nhất là chúng ta nên hủy cấu trúc phương thức
Bây giờ chúng ta có thể tiếp tục tạo các biến để lưu trữ các tham số URL mà chúng ta muốn. Đoạn mã dưới đây cho thấy cách bạn có thể thực hiện điều đó.
Lưu ý rằng các giá trị
Bạn luôn có thể ghi các biến này vào bảng điều khiển để xem kết quả.
Bây giờ bạn đã hiểu cách lấy các tham số này từ URL, hãy bắt đầu bằng cách xây dựng cấu trúc của các biểu mẫu.
Đoạn trích trên cho thấy cấu trúc cơ bản của giao diện người dùng mà bạn sẽ thấy khi đến tuyến đường quên mật khẩu. Bạn sẽ thấy văn bản trong thẻ đoạn văn bên dưới văn bản in đậm “Quên mật khẩu”.
Với loại văn bản như trên, bạn đang cải thiện trải nghiệm người dùng của những người truy cập vào trang quên mật khẩu của ứng dụng. Bạn đang đảm bảo với họ rằng việc họ quên mật khẩu không phải là vấn đề lớn, vì vậy không cần phải cảm thấy tệ về điều đó.
Bạn không nhất thiết phải sử dụng chính xác văn bản trên. Bạn chỉ cần đảm bảo rằng bất kỳ văn bản nào bạn đang sử dụng đều có giọng điệu đồng cảm.
Bây giờ, chúng ta hãy chuyển sang phần quan trọng của biểu mẫu này, đó là nơi chúng ta cần khai báo một hàm sẽ gửi email mà người dùng nhập vào trường nhập liệu đến phần phụ trợ.
Từ đoạn trích trên, bạn sẽ thấy rằng chúng ta đang nhập điểm cuối API mà chúng ta sẽ gửi yêu cầu POST đến — và đó là lý do tại sao chúng ta truyền nó dưới dạng biến cho khóa
Yêu cầu POST nhận địa chỉ email của người dùng dưới dạng tải trọng, sau đó sẽ được xác thực ở phần phụ trợ và JWT sẽ được tạo cho địa chỉ email đó, được sử dụng để ủy quyền cho quy trình đặt lại mật khẩu của người dùng.
Khi bạn thực hiện hãy xem đoạn trích ở trên, bạn sẽ thấy rằng chúng ta đang sử dụng một số hàm gọi lại trạng thái đã được khai báo của các biến trạng thái.
Một ví dụ là hàm
Bạn cũng sẽ thấy rằng có một vài hàm gọi lại trạng thái trong đoạn trích ở trên, như
Các setter được lấy từ khai báo các biến trạng thái. Xem chúng bên dưới.
Các thông báo lỗi hoặc thành công nhận được từ phần phụ trợ có thể được hiển thị trong UI để cho người dùng biết trạng thái của hành động của họ.
Bạn sẽ nhận thấy rằng chúng tôi đang sử dụng các thành phần modal tùy chỉnh để hiển thị thông báo. Các thành phần này nhận thông báo dưới dạng props và chúng có thể được sử dụng lại trên toàn bộ cơ sở mã. Hãy xem cấu trúc của các thành phần bên dưới.
Bạn có thể định kiểu cho các thành phần này theo cách riêng để có thể phân biệt được hộp thoại "error" với hộp thoại "success". Quy ước chung là sử dụng màu đỏ cho thông báo lỗi và màu xanh lá cây cho thông báo thành công. Cách bạn chọn định dạng các thành phần này hoàn toàn tùy thuộc vào bạn.
Ngoài tất cả những gì đã nói, chúng ta cần một cách để xác minh rằng kiểu dữ liệu chính xác đang được truyền dưới dạng prop cho thành phần modal. Điều này có thể đạt được bằng mô-đun "prop-type" trong react.
Quy trình kiểm tra kiểu trong đoạn mã trên đảm bảo rằng dữ liệu mà thành phần nhận được phải là một chuỗi và dữ liệu này là bắt buộc. Nếu thành phần không nhận được prop có giá trị chuỗi, React sẽ báo lỗi.
Bây giờ chúng ta đã đề cập đến khía cạnh quan trọng của biểu mẫu đầu tiên và các khối xây dựng của những gì chúng ta sẽ sao chép trong tuyến reset-password. Hãy bắt đầu bằng cách xem bố cục của biểu mẫu bên dưới.
Vì chúng ta đã tìm hiểu những điều cơ bản của biểu mẫu đầu tiên trong phần trước, nên đoạn trích ở trên chứa gần như cùng một nội dung trong biểu mẫu trước.
Bạn có thể thấy cách chúng ta đọc các tham số từ URL và các khai báo của các biến lỗi đặt lại mật khẩu và thành công.
Bạn cũng sẽ nhận thấy cách chúng tôi hiển thị có điều kiện biểu mẫu đặt lại mật khẩu bằng cách kiểm tra xem các biến
Bây giờ, hãy xem xét hàm xử lý mà chúng ta sẽ sử dụng để gửi mật khẩu mới của người dùng — kết hợp với mã thông báo và email cho mục đích xác minh — đến phần phụ trợ thông qua điểm cuối API.
Đoạn mã trên là một hàm xử lý không đồng bộ. Chúng tôi sử dụng nó để gửi yêu cầu POST với mật khẩu mới của người dùng, mã thông báo truy cập và địa chỉ email — mà chúng tôi lấy từ các tham số truy vấn tại phân đoạn URL.
Khi bạn xem đoạn trích ở trên, bạn sẽ thấy cách chúng tôi sử dụng phương thức
Thực hiện điều này cũng giúp tăng số liệu về trải nghiệm người dùng tốt, vì nó ngăn người dùng tìm kiếm liên kết hoặc nút đưa họ trở lại trang đăng nhập.
Cảm ơn bạn đã đọc. Tôi hy vọng bài viết này hữu ích!
Mặc dù vậy, có rất nhiều tài nguyên xung quanh việc xây dựng các ứng dụng được xác thực bằng Next.js. Vâng, thậm chí còn có một dự án nguồn mở thực sự xử lý xác thực từ đầu.
Nhưng phạm vi của bài viết này không xoay quanh toàn bộ khái niệm xác thực. Chúng tôi chỉ chọn một mẫu cụ thể của quy trình xác thực: luồng "đặt lại mật khẩu" và cách triển khai luồng này ở phía máy khách — giao diện người dùng — của ứng dụng web.
Trong bài viết này, bạn sẽ thấy cách triển khai tính năng này bằng cách sử dụng công cụ truy xuất dữ liệu phổ biến, Axios — tính năng định tuyến động tích hợp sẵn của Next.js và hook
useRouter
.Tổng quan về luồng đặt lại mật khẩu
Kể từ khi web ra đời, các Kỹ sư luôn nỗ lực cung cấp giải pháp cho các vấn đề phát sinh trong những ngày đầu của web — và tính bảo mật của phần mềm trên web cũng không ngoại lệ.Có một câu nói phổ biến như sau: "Người dùng sẽ luôn quên mật khẩu của họ" và đó là sự thật tuyệt đối. Nhiều người thậm chí còn sợ trang "đặt lại mật khẩu" vì, nghĩ lại thì, sau khi dành nhiều thời gian cố gắng đoán mật khẩu của mình — tất cả đều vô ích — họ cảm thấy thất vọng hoặc tức giận khi truy cập vào trang cụ thể này.
Khi chúng ta tạo giao diện người dùng, chúng ta cũng nên cố gắng hết sức để làm cho trải nghiệm trở nên thú vị đối với người dùng. Mặc dù chúng ta rất muốn vượt qua quy trình đặt lại mật khẩu, nhưng UX của quy trình đó cũng nên được ưu tiên.
Có thể thấy quy trình chung của quy trình đặt lại mật khẩu như bên dưới.
- Người dùng cảm thấy thất vọng sau khi cố gắng đăng nhập mà không thành công. Họ nhấp vào liên kết "đặt lại mật khẩu" và họ được chuyển hướng đến trang tương ứng. Giao diện người dùng mà họ thấy là biểu mẫu web thông thường sẽ nhập địa chỉ email hoặc tên người dùng của họ.
- Khi họ nhập địa chỉ email hoặc tên người dùng của mình vào trường nhập liệu, họ nhấp vào nút có văn bản chung "gửi email cho tôi liên kết khôi phục".
- Họ nhận được xác nhận rằng liên kết bảo mật đã được gửi đến email của họ. Đôi khi, văn bản xác nhận này có thể được hiển thị trong thành phần giống như thẻ hoặc hộp thoại mờ dần theo thời gian.
- Liên kết được gửi đến địa chỉ email của họ chứa JWT và
user_id
của họ hoặc trong trường hợp này là địa chỉ email của họ. - Khi nhấp vào liên kết đó, họ sẽ được chuyển hướng đến tuyến đường/trang nơi họ có thể nhập mật khẩu mới của mình. Tuyến đường mà người dùng sẽ đi có thể có dạng bên dưới
Mã:
https://localhost:3000/reset-password/user-email/JWToken
- Phần cuối cùng của luồng là xác minh xem JWT được tạo có được liên kết với tài khoản của người dùng hay không. Nếu không, chúng tôi sẽ báo lỗi bằng cách hiển thị thông báo lỗi thu được từ phần phụ trợ.
Hiểu về các tuyến động
Trong phần này, chúng ta sẽ tìm hiểu khái niệm về các tuyến động bằng cách minh họa nó bằng cấu trúc thư mục của một dự án Next.js và xem cách chúng ta sẽ tích hợp nó vào tính năng "đặt lại mật khẩu". Nhưng trước tiên, hãy thiết lập một ứng dụng Next.js.
Mã:
npx create-next-app app-name
Trong đoạn trích bên dưới, bạn sẽ thấy cấu trúc cơ bản của các tệp mà chúng ta sẽ tương tác trong bài viết này.
Mã:
└── pages / ├── forget-password/ │ └── [token]/ │ └── [email].js ├── _app.js └── index.js
Và vì việc triển khai luồng "đặt lại mật khẩu" là mối quan tâm hàng đầu của chúng tôi, tôi nghĩ tốt nhất là chúng ta nên hạn chế sự lộn xộn. Bây giờ, chúng ta hãy hiểu một chút về cấu trúc này.
Bạn sẽ thấy rằng chúng ta có thư mục
forgot-password
trong thư mục pages
, chứa một số tệp. Nhưng quy ước đặt tên của các tệp này khá khác so với cách đặt tên của các tệp khác. Tên của các tệp — token và email.js — được bao bọc trong một cặp dấu ngoặc vuông.Các thư mục và tệp được đặt tên như thế này được gọi là các tuyến động và vì chúng nằm trong thư mục
pages
, chúng tự động trở thành các tuyến mà trình duyệt có thể truy cập. Chúng là động vì các giá trị mà các tuyến này sử dụng không tĩnh, nghĩa là chúng thay đổi theo thời gian.Mẫu đặt tên tệp này thường được thấy khi bạn quyết định xây dựng một blog hoặc khi bạn tương tác với dữ liệu thay đổi dựa trên loại người dùng đã đăng nhập vào ứng dụng. Bạn có thể xem cách tôi sử dụng tính năng này của Next.js khi tôi xây dựng blog của mình. Bạn cũng có thể tìm hiểu thêm về tính năng này trong tài liệu Next.js.
Trong thư mục
forgot-password
, đường dẫn đến giao diện người dùng chứa biểu mẫu quên mật khẩu có thể được truy cập tại đây. Hãy xem bên dưới.
Mã:
http://localhost:3000/forgot-password/token/email
token
và email
sẽ luôn thay đổi dựa trên người dùng đang cố gắng đặt lại mật khẩu của họ. Mã thông báo và email của người dùng A sẽ khác với người dùng B.Đọc tham số URL bằng Hook Userouter
HookuseRouter
trong Next.js có thể được sử dụng để đạt được nhiều triển khai giao diện người dùng thực tế — từ ý tưởng phổ biến là triển khai một mục thanh điều hướng đang hoạt động với khóa .pathname
, cho đến các tính năng phức tạp hơn.Bây giờ, chúng ta hãy cùng xem cách đọc tham số URL từ các tuyến động bằng hook
useRouter
nhé? Để thực hiện điều đó, trước tiên bạn phải nhập mô-đun vào trang/thành phần của mình.
Mã:
import { useRouter } from 'next/router'export default function PageComponent({ children }) { const router = useRouter() return ( {/* nội dung trang nằm dưới */} {children} )}
query
của hook thay vì thực hiện điều gì đó như thế này: router.query
. Chúng ta sẽ làm một điều tương tự bên dưới.
Mã:
import { useRouter } from 'next/router'const { query } = useRouter()
Mã:
const token = query.tokenconst email = query.email
query.token
và query.email
là kết quả của tên các tệp. Nhớ lại từ cấu trúc thư mục trong thư mục forgot-password
nơi chúng ta có các tệp [email].js
và [token]
. Nếu bạn đổi tên các tệp đó thành [userEmail].js
và [userToken]
tương ứng, thì mẫu gán các biến này sẽ giống như bên dưới.
Mã:
const token = query.userTokenconst email = query.userEmail
Bây giờ bạn đã hiểu cách lấy các tham số này từ URL, hãy bắt đầu bằng cách xây dựng cấu trúc của các biểu mẫu.
Xây dựng biểu mẫu
Trong phần này, chúng tôi sẽ hướng dẫn bạn quy trình xây dựng biểu mẫu và cách bạn có thể sử dụng Axios để thực hiện việc truy xuất dữ liệu thông qua điểm cuối API tùy ý. Chúng tôi sẽ không tập trung vào kiểu dáng của các biểu mẫu này và giải thích về cấu trúc. Tôi cho rằng bạn đã biết cách cấu trúc và kiểu dáng của biểu mẫu React cơ bản. Vì vậy, hãy bắt đầu với bố cục biểu mẫu trên tuyến đường forget-password.
Mã:
import React from 'react'import axios from 'axios'import { ErrModal, SuccessModal } from '../components/Modals'export const DefaultResetPassword = () => { const [email, setEmail] = React.useState('') const [loading, setLoading] = React.useState(false) const handleForgot = () => { } // chúng ta sẽ thấy kết quả trả về này sau ( [HEADING=1]Quên mật khẩu[/HEADING]
Bạn không đơn độc. Tất cả chúng ta đều đã từng ở đây vào một thời điểm nào đó.
Địa chỉ email setEmail(e.target.value)} required /> {!loading ? ‘Bảo mật link’: ‘Đang gửi...’} )}
Mã:
Bạn không đơn độc. Tất cả chúng ta đều từng ở đây vào một thời điểm nào đó
Bạn không nhất thiết phải sử dụng chính xác văn bản trên. Bạn chỉ cần đảm bảo rằng bất kỳ văn bản nào bạn đang sử dụng đều có giọng điệu đồng cảm.
Bây giờ, chúng ta hãy chuyển sang phần quan trọng của biểu mẫu này, đó là nơi chúng ta cần khai báo một hàm sẽ gửi email mà người dùng nhập vào trường nhập liệu đến phần phụ trợ.
Mã:
import { authEndpoints } from '../endpoints'export const DefaultResetPassword = () => { const handleForgot = async (e) => { e.preventDefault() thử { setLoading(true) const response = await axios({ phương thức: 'POST', url: authEndpoints.recover, dữ liệu: { email, }, tiêu đề: { 'Content-Type': 'application/json', }, }) setResestSuccess(response.data.msg) setLoading(false) setResetError('') } catch (lỗi) { setLoading(false) const { dữ liệu } = error.response setResetError(data.msg) setResestSuccess(null) } } return {/* ...thành phần biểu mẫu trước đó */}}
url
trong phương thức Axios.Yêu cầu POST nhận địa chỉ email của người dùng dưới dạng tải trọng, sau đó sẽ được xác thực ở phần phụ trợ và JWT sẽ được tạo cho địa chỉ email đó, được sử dụng để ủy quyền cho quy trình đặt lại mật khẩu của người dùng.
Mã:
setResestSuccess(response.data.msg)setLoading(false)setResetError('')catch (error) { setLoading(false) const { data } = error.response setResetError(data.msg) setResestSuccess(null)}
Một ví dụ là hàm
setLoading
có giá trị được đặt thành true
trong khối try
. Sau đó, giá trị của hàm được đặt thành false khi dữ liệu đã được gửi thành công. Và nếu không, chúng ta có khối catch
sẽ "bắt" lỗi và hiển thị thông báo lỗi mà chúng ta đã giải cấu trúc từ điểm cuối.Bạn cũng sẽ thấy rằng có một vài hàm gọi lại trạng thái trong đoạn trích ở trên, như
setResestSuccess
và setResetError
.Các setter được lấy từ khai báo các biến trạng thái. Xem chúng bên dưới.
Mã:
nhập React từ 'react'nhập { ErrModal, SuccessModal } từ '../components/Modals'export const DefaultResetPassword = () => { const [resetSuccess, setResestSuccess] = React.useState() const [resetError, setResetError] = React.useState() return ( {resetError ? : null} {resetSuccess ? : null} {/* form content */} )}
Bạn sẽ nhận thấy rằng chúng tôi đang sử dụng các thành phần modal tùy chỉnh để hiển thị thông báo. Các thành phần này nhận thông báo dưới dạng props và chúng có thể được sử dụng lại trên toàn bộ cơ sở mã. Hãy xem cấu trúc của các thành phần bên dưới.
Mã:
export const SuccessModal = ({ message }) => { return (
{message}
)}export const ErrModal = ({ message }) => { return (
{message}
)}
Ngoài tất cả những gì đã nói, chúng ta cần một cách để xác minh rằng kiểu dữ liệu chính xác đang được truyền dưới dạng prop cho thành phần modal. Điều này có thể đạt được bằng mô-đun "prop-type" trong react.
Mã:
propTypes.ErrModal = { message: propTypes.string.isRequired,}propTypes.SuccessModal = { message: propTypes.string.isRequired,}
Bây giờ chúng ta đã đề cập đến khía cạnh quan trọng của biểu mẫu đầu tiên và các khối xây dựng của những gì chúng ta sẽ sao chép trong tuyến reset-password. Hãy bắt đầu bằng cách xem bố cục của biểu mẫu bên dưới.
Mã:
import axios from "axios";import React from “react”;import Head from “next/head”;import { useRouter } from "next/router";import { SuccessModal, ErrModal } from "../components/Modals";const ResetPassword = () => { const [newPassword, setNewPassword] = React.useState(""); const [loading, setLoading] = React.useState(false); const [resetPasswordSuccess, setResetPasswordSuccess] = React.useState(); const [resetPasswordError, setResetPasswordError] = React.useState(); const { query } = useRouter(); const token = query.token; const email = query.email; const resetPassword = () => { } // sẽ xuất hiện sau... return ( Đặt lại mật khẩu {email && token ? ( {resetPasswordSuccess ? ( ) : ( null )} {resetPasswordError ? ( ) : ( null )} [HEADING=1]Đặt lại mật khẩu[/HEADING]
Vui lòng nhập mật khẩu mới của bạn password
Password* setNewPassword(e.target.value)} /> {!loading ? "Reset" : "Đang xử lý..."} ) : (
Trang bạn đang cố gắng truy cập không khả dụng
)} );};
Bạn có thể thấy cách chúng ta đọc các tham số từ URL và các khai báo của các biến lỗi đặt lại mật khẩu và thành công.
Mã:
const [resetPasswordSuccess, setResetPasswordSuccess] = React.useState()const [resetPasswordError, setResetPasswordError] = React.useState()const { query } = useRouter()const token = query.tokenconst email = query.email
email
và token
có trong URL hay không; nếu các biến này là sai (tức là chúng không có trong URL), chúng tôi sẽ hiển thị một văn bản cho biết trang mà chúng đang tìm kiếm không khả dụng.
Mã:
{ email && token ? ( ) : (
Trang bạn đang cố gắng truy cập không khả dụng
)}
Mã:
import { authEndpoints } from '../endpoints'const resetPassword = async (e) => { e.preventDefault() try { setLoading(true) const response = await axios({ method: 'POST', url: authEndpoints.resetPassword, data: { token, email, password: newPassword, }, headers: { 'Content-Type': 'application/json', }, }) setResetPasswordSuccess(response.data.msg) setLoading(false) setTimeout(() => { router.push('/') }, 4000) setResetPasswordError('') } catch (error) { setLoading(false) setResetPasswordError(error.response.data.msg) setResetPasswordSuccess(null) }}
Mã:
setTimeout(() => { router.push('/')}, 4000)
setTimeout
trong JavaScript và hook useRouter
của Next.js để chuyển hướng người dùng đến trang chủ — trong trường hợp này là trang đăng nhập — sau bốn giây (bạn có thể giảm khung thời gian này nếu muốn), để họ có thể đăng nhập lại.Thực hiện điều này cũng giúp tăng số liệu về trải nghiệm người dùng tốt, vì nó ngăn người dùng tìm kiếm liên kết hoặc nút đưa họ trở lại trang đăng nhập.
Suy nghĩ cuối cùng
Có rất nhiều thông tin về các phương pháp hay nhất và các mẫu thiết kế đặt lại mật khẩu tuyệt vời. Bài viết này chỉ là một triển khai giao diện người dùng của luồng đặt lại mật khẩu, trong đó cũng tính đến vấn đề trải nghiệm người dùng. Chỉ tạo tính năng đặt lại mật khẩu mà không cân nhắc đến UX của những người sẽ sử dụng tính năng này là chưa đủ.Cảm ơn bạn đã đọc. Tôi hy vọng bài viết này hữu ích!
Đọc thêm về Tạp chí Smashing
- “Cách triển khai xác thực trong Next.js với Auth0,” Facundo Giuliani
- “Lấy dữ liệu động trong ứng dụng Next.js đã xác thực,” Caleb Olojo
- “Bản địa hóa ứng dụng Next.js của bạn,” Átila Fassina
- “Tình trạng xác thực hiện tại: Chúng ta có vấn đề về mật khẩu,” Drew Thomas