Skip to content

PRD: Xác thực & xác minh tài khoản

ModuleQuản lý Người dùng (CORE-01)PRD IDPRD-AUTH-001
StatusShippedOwnerIdentity squad
Date2026-05-25Versionv1.0
Packages@nx/identity · apps/clientURDAUTH

TL;DR

Cho phép mọi người dùng chứng minh quyền sở hữu tài khoản và tự khôi phục quyền truy cập. Người dùng sign-up và sign-in bằng username, email hoặc điện thoại kèm mật khẩu, xác minh email và điện thoại bằng mã một lần (OTP), và đặt lại mật khẩu đã quên trọn vẹn - không cần mở ticket hỗ trợ. Kết quả: identifier mà các module khác có thể tin cậy, và một lối khôi phục tự phục vụ giúp chủ cửa hàng và nhân viên không bị khóa ngoài.

1. Bối cảnh & Vấn đề

Quản lý Người dùng là nền tảng của nền tảng - mọi module khác đều tin cậy danh tính và phạm vi mà nó cấp. Sign-up và sign-in bằng mật khẩu đã có, nhưng tài khoản chưa thể chứng minh quyền sở hữu một email hay điện thoại, và người dùng quên mật khẩu không có lối tự khôi phục. Khi chưa xác minh, một identifier email hay điện thoại chỉ là một chuỗi chưa được chứng thực; khi chưa có luồng reset, quên mật khẩu nghĩa là bị khóa cứng, chỉ có can thiệp thủ công mới gỡ được.

Đợt này lấp các khoảng trống đó trên nền các primitive sign-up / sign-in / băm mật khẩu sẵn có: bổ sung xác minh email và điện thoại bằng OTP, luồng đặt lại mật khẩu khi quên, liên kết identifier, và các màn hình client tiêu thụ chúng - đáp ứng các yêu cầu xác minh và khôi phục mà tính năng AUTH liệt kê là Must.

2. Mục tiêu & Không làm

Mục tiêu

  • Sign-up tạo tài khoản, profile, identifier và default settings trong một thao tác duy nhất, tất cả hoặc không, role Owner được gán tự động.
  • Sign-in bằng bất kỳ identifier đã xác minh (username / email / điện thoại) + mật khẩu, trả về một session token có phạm vi (role, phạm vi organizer, merchant).
  • Đổi mật khẩu với mật khẩu hiện tại được xác minh trước; mật khẩu luôn lưu dạng băm.
  • Xác minh email bằng OTP - yêu cầu mã → gửi mã → identifier được đánh dấu đã xác minh.
  • Xác minh điện thoại bằng OTP theo cùng luồng yêu cầu/gửi mã.
  • Đặt lại mật khẩu đã quên trọn vẹn - yêu cầu reset → xác minh mã → đặt mật khẩu băm mới.
  • Liên kết một email hoặc điện thoại đã xác minh vào một tài khoản đã đăng nhập.
  • Cấu hình mail và HTML template được seed từ database để mail xác minh / reset có thể cấu hình, không hardcode.
  • Màn hình client cho việc xác minh identifier và đặt lại mật khẩu.

Không làm (Non-Goals)

  • Luồng đăng nhập bên thứ ba OAuth / OAuth2 - scheme đã định nghĩa, luồng đăng nhập chưa xây (URD-AUTH-014).
  • Bắt buộc xác thực hai yếu tố - credential scheme đã có, việc bắt buộc chưa xây (URD-AUTH-013).
  • Quản lý phiên và thu hồi từ xa - session token là stateless.
  • Mời người dùng qua email hoặc điện thoại.
  • Ghi lịch sử / nhật ký đăng nhập (audit).

3. Success Metrics

Chỉ sốMục tiêu / tín hiệu
Hoàn tất xác minhTỷ lệ identifier email/điện thoại đạt trạng thái đã xác minh qua OTP tăng dần
Tự khôi phụcSố mật khẩu quên được giải quyết qua luồng reset, không cần hỗ trợ thủ công
Tính toàn vẹn sign-inKhông có ca sign-in thành công trên identifier chưa xác minh hoặc đã vô hiệu/bị chặn
An toàn credential100% mật khẩu lưu dạng băm; không lưu plain-text
Độ tin cậy OTPTỷ lệ gửi OTP thành công; lỗi hết hạn/quá số lần thử được xử lý mượt mà

4. Personas & Use Case

PersonaMục tiêu trong tính năng này
OwnerSign-up, bảo vệ tài khoản, xác minh email/điện thoại, khôi phục mật khẩu đã mất
Employee / CashierSign-in bằng thông tin riêng, đổi hoặc đặt lại mật khẩu
CustomerXác minh một identifier và khôi phục quyền truy cập tài khoản

Kịch bản chính: sign-up (tài khoản + profile + identifier + settings, role Owner) → xác minh email/điện thoại bằng OTP → sign-in bằng identifier đã xác minh để nhận token có phạm vi → đổi mật khẩu, hoặc - nếu quên - yêu cầu reset, xác minh mã và đặt mật khẩu mới → tùy chọn liên kết thêm một email hoặc điện thoại đã xác minh.

5. User Stories

  • Là một người dùng mới, tôi muốn sign-up bằng username và mật khẩu trong một bước, để tài khoản, profile, identifier và default settings được tạo cùng nhau.
  • Là một người dùng, tôi muốn xác minh email bằng mã một lần, để nền tảng tin cậy identifier đó và tôi có thể sign-in bằng nó.
  • Là một người dùng, tôi muốn xác minh điện thoại bằng cùng luồng OTP, để điện thoại trở thành một identifier dùng được, đáng tin.
  • Là một người dùng, tôi muốn sign-in bằng bất kỳ identifier đã xác minh kèm mật khẩu, để nhận một session token mang role và phạm vi của mình.
  • Là một người dùng, tôi muốn đổi mật khẩu sau khi xác nhận mật khẩu hiện tại, để xoay vòng credential an toàn.
  • Là một người dùng quên mật khẩu, tôi muốn yêu cầu reset, xác minh mã và đặt mật khẩu mới, để khôi phục quyền truy cập mà không cần hỗ trợ.
  • Là một người dùng đã đăng nhập, tôi muốn liên kết một email hoặc điện thoại đã xác minh vào tài khoản, để có thêm cách sign-in và khôi phục.

6. Functional Requirements

#Yêu cầuURD ref
FR-1Sign-up bằng username + mật khẩu; tài khoản, profile, identifier và default settings tạo trong một thao tác duy nhất tất-cả-hoặc-không, gán role OwnerURD-AUTH-001..003
FR-2Sign-in bằng bất kỳ identifier đã xác minh (username / email / điện thoại) + mật khẩu; trả session token mang role và phạm vi organizer / merchantURD-AUTH-004..005
FR-3Mật khẩu được băm an toàn trước khi lưu và không bao giờ lưu plain-textURD-AUTH-006
FR-4Đổi mật khẩu với mật khẩu hiện tại được xác minh trướcURD-AUTH-007
FR-5Xác minh email bằng OTP: yêu cầu mã → gửi mã → identifier được đánh dấu đã xác minhURD-AUTH-008
FR-6Xác minh điện thoại bằng OTP theo cùng luồng yêu cầu/gửi mãURD-AUTH-009
FR-7Đặt lại mật khẩu đã quên: yêu cầu reset → xác minh mã → đặt mật khẩu băm mớiURD-AUTH-010
FR-8Liên kết một email hoặc điện thoại đã xác minh vào tài khoản đã đăng nhậpURD-AUTH-011
FR-9Identifier đã xác minh tham gia kiểm tra trùng lặp toàn cục (một email/điện thoại đã xác minh thuộc một người dùng)URD-AUTH-008..009
FR-10Cấu hình mail và HTML template được seed từ database, để mail xác minh / reset có thể cấu hìnhURD-AUTH-008..010

Nội dung yêu cầu đầy đủ và tiêu chí chấp nhận nằm trong URD Quản lý Người dùng. PRD này tham chiếu, không lặp lại.

7. Non-Functional Requirements

Khía cạnhYêu cầu
Toàn vẹn dữ liệuSign-up là một thao tác duy nhất - nếu bất kỳ bước nào thất bại, không tạo gì (tài khoản, profile, identifier, settings)
An toàn credentialMật khẩu băm trước khi lưu; reset đặt mật khẩu băm; response reset không bao giờ mang session token
Tenancy & authzSession token mang role và phạm vi organizer / merchant; mọi thao tác trừ sign-in / sign-up đều cần xác thực
Độ bền OTPMã OTP có thời hạn và giới hạn số lần thử; ca mã hết hạn và quá số lần trả lỗi rõ ràng
StatelessSession token là stateless - thay đổi permission có hiệu lực ở lần sign-in kế tiếp
Khả năng cấu hìnhNội dung mail điều khiển bởi cấu hình và HTML template seed từ DB, không phải chuỗi hardcode
i18nNhãn, trạng thái và nội dung mail ở phần hiển thị là song ngữ ({ en, vi })

8. UX & Luồng

Màn hình chính (trong apps/client): một trang verify tiêu thụ endpoint yêu cầu/gửi OTP, và một trang quên-mật-khẩu / đặt-lại-mật-khẩu điều khiển luồng reset.

9. Dữ liệu & Domain

EntityVai trò
UserDanh tính đã xác thực, sở hữu credential, identifier, profile và settings
CredentialBí mật mật khẩu băm dùng để xác thực
IdentifierMột giá trị đăng nhập (username / email / điện thoại), trùng lặp toàn cục theo từng loại, mang cờ verified
OTP sessionTrạng thái ngắn hạn hỗ trợ xác minh và reset (yêu cầu → gửi, có thời hạn và giới hạn số lần)
Cấu hình mail + templateCấu hình mail và HTML template seed từ DB cho mail xác minh / reset

Chỉ mang tính khái niệm - schema đầy đủ và bất biến trong mô hình domain identity.

10. Phụ thuộc & Giả định

Phụ thuộc

  • User Account (URD-USR) - người dùng, identifier và vòng đời verified mà tính năng này điều khiển.
  • Roles & Scoping (URD-ROLE) - sign-up gán role Owner; sign-in phân giải role và phạm vi vào token.
  • User Configuration (URD-CFG) - default settings tạo trong sign-up một-thao-tác-duy-nhất.
  • Gửi mail cho mã OTP và mã reset; apps/client cho các màn hình verify và reset.

Giả định

  • Một identifier (email/điện thoại) có thể nhận được để OTP được gửi tới.
  • Cấu hình mail và template được seed trước khi gửi mail xác minh / reset.
  • Username là bắt buộc và mặc định được coi là đã xác minh; email và điện thoại khởi đầu chưa xác minh.

11. Rủi ro & Câu hỏi mở

Rủi ro / câu hỏiGiảm thiểu / trạng thái
Sign-up dở dang có thể để lại mảnh tài khoản mồ côiSign-up là tất-cả-hoặc-không; bất kỳ thất bại nào cũng cuộn lại toàn bộ
Dò mã OTP / phát lạiMã có thời hạn và giới hạn số lần thử; lỗi hết hạn/quá số lần rõ ràng
Response reset rò rỉ session tokenSession token đã bị bỏ khỏi response đặt-lại-mật-khẩu
Xác minh email khi sign-up hiện đang tắt trong codeKhoảng trống đã biết - sign-up mới có thể cần một luồng verify riêng trước khi sign-in bằng email; xem developer docs
Chưa bắt buộc 2FA / chưa có đăng nhập OAuthNgoài phạm vi đợt này; credential scheme đã có, việc bắt buộc/luồng đăng nhập là planned

12. Release Plan & Launch Criteria

Khía cạnhKế hoạch
PhaseP1 (nền tảng) - xem danh mục tính năng URD
RolloutMọi người dùng; không feature flag
MigrationSeed cấu hình mail và HTML template; thêm các trường verified tùy chọn vào user schema
Launch criteriaXác minh OTP email + điện thoại trọn vẹn; đặt-lại-mật-khẩu trọn vẹn; sign-in từ chối identifier chưa xác minh / đã vô hiệu; mật khẩu lưu dạng băm
MonitoringTỷ lệ gửi OTP + xác minh thành công, hoàn tất luồng reset, lý do sign-in thất bại (chưa xác minh / sai mật khẩu / bị chặn)

13. FAQ

Tôi có thể sign-in bằng email hoặc điện thoại chưa xác minh không? Không - sign-in cần một identifier đã xác minh. Username được xác minh tự động; email và điện thoại phải qua OTP trước.

Luồng OTP hoạt động ra sao? Yêu cầu một mã cho email hoặc điện thoại (một session token được trả về), sau đó gửi mã; thành công thì identifier được đánh dấu đã xác minh. Mã có thời hạn và giới hạn số lần thử.

Nếu tôi quên mật khẩu thì sao? Yêu cầu reset, xác minh mã gửi qua email/tin nhắn, rồi đặt mật khẩu mới - nó được băm trước khi lưu, và response reset không bao giờ trả session token.

Mail xác minh và reset đến từ đâu? Cấu hình mail và HTML template được seed từ database, nên nội dung có thể cấu hình thay vì hardcode.

Có hỗ trợ OAuth hay xác thực hai yếu tố không? Không trong đợt này - cả hai scheme đã được định nghĩa nhưng luồng đăng nhập / việc bắt buộc là planned, chưa xây.

Tài liệu liên quan

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.