Thiết kế Kỹ thuật Phần mềm

Module Xác thực
AUTH
Phiên bản1.0
Hệ thốngHệ thống Xác thực
ModuleAUTH - Authentication
Ngày2026-08-05
Tác giảNam Nguyen
Trạng tháiBản nháp
SRS Liên quanAuthentication SRS

Mục lục

1. Tổng quan

1.1 Mục đích

Tài liệu này mô tả các quyết định thiết kế kỹ thuật cho module Authentication.

1.2 Yêu cầu được Giải quyết

Danh mụcMã Yêu cầuPhần Thiết kế
Chức năngFR-001 - FR-020Phần 3, 5
Phi chức năngNFR-001 - NFR-007Phần 6

2. Kiến trúc

2.1 Kiểu Kiến trúc

Khía cạnhQuyết địnhGiải quyết
MẫuNestJS Module (Monolith)NFR-007
Thư viện Xác thựcBetter AuthFR-001 - FR-009
ORMDrizzle ORMTất cả yêu cầu dữ liệu
Cơ sở dữ liệuPostgreSQL (auth_db)NFR-006
Chiến lược TokenJWT (access + refresh)NFR-004

2.2 Các Quyết định Thiết kế Quan trọng

#Quyết địnhLý doGiải quyết
1Sử dụng Better Auth Xử lý quản lý phiên, tạo token, xác minh thông tin đăng nhập FR-001 - FR-009
2PostgreSQL Đảm bảo ACID, hỗ trợ JSON, hệ sinh thái trưởng thành NFR-006
3JWT access + refresh tokens Truy cập không trạng thái cho hiệu suất, refresh cho bảo mật NFR-004
4bcrypt mã hóa mật khẩu Tiêu chuẩn ngành, chi phí thích ứng NFR-003
5Redis cho giới hạn tốc độ Tra cứu nhanh, hỗ trợ TTL NFR-005

3. Thiết kế Thành phần

3.1 Sơ đồ Thành phần

AUTH Component Diagram
Hình 1: Các Thành phần Module AUTH

3.2 Cấu trúc Module

src/
  auth/
    auth.module.ts
    auth.controller.ts
    auth.service.ts
    auth.guard.ts
    dto/
  users/
    users.module.ts
    users.controller.ts
    users.service.ts
  roles/
    roles.module.ts
    roles.controller.ts
    roles.service.ts
  organizations/
    organizations.module.ts
    organizations.controller.ts
    organizations.service.ts
  teams/
    teams.module.ts
    teams.controller.ts
    teams.service.ts
  invitations/
    invitations.module.ts
    invitations.controller.ts
    invitations.service.ts

3.3 Ánh xạ Thành phần đến Yêu cầu

Thành phầnTrách nhiệmGiải quyết
AuthControllerĐăng nhập, đăng ký, đăng xuất, refresh, đặt lại mật khẩuFR-001 - FR-009
AuthServiceTạo token, mã hóa mật khẩu, xác minhNFR-003, NFR-004
UsersControllerThao tác CRUD người dùngFR-010
RolesControllerQuản lý vai trò, phân quyềnFR-011
SocialAuthControllerĐăng nhập mạng xã hội, liên kết/gỡ liên kết tài khoảnFR-012
SessionControllerLiệt kê phiên, thu hồi, giả mạoFR-013, FR-014
OrganizationsControllerCRUD tổ chức, thành viên, vai tròFR-015
TeamsControllerCRUD nhóm, quản lý thành viênFR-016
InvitationsControllerMời, chấp nhận, từ chối, thu hồi, gửi lại, xác minh lời mờiFR-017, FR-018, FR-019, FR-020
Email Queue WorkerConsume RabbitMQ events (verification, password reset), gọi EMAIL module APIFR-001, FR-005, FR-008
SMS Queue WorkerConsume RabbitMQ events (verification, password reset), gọi SMS module APIFR-006, FR-009
AuthGuardXác minh JWT, bảo vệ tuyến đườngNFR-004

4. Kiến trúc Dữ liệu

4.1 Cơ sở dữ liệu

Cơ sở dữ liệu: auth_db (PostgreSQL)

Xem thêm: Thiết kế Cơ sở dữ liệu

4.2 Giải quyết Yêu cầu Dữ liệu

Yêu cầu SRSGiải pháp Thiết kếBảng DB
FR-001 Đăng kýChèn bản ghi người dùng + tài khoảnauth_users, auth_accounts
FR-002 Đăng nhậpTruy vấn người dùng, xác minh mật khẩu, tạo phiênauth_users, auth_sessions
FR-008/FR-009 Xác minhLưu mã xác minh, cập nhật trạng thái người dùngauth_verification, auth_users
FR-011 Vai tròRBAC với vai trò và quyền hạnauth_roles, auth_user_roles

5. Thiết kế API

5.1 Ánh xạ Endpoint đến Yêu cầu

Phương thứcĐường dẫnMô tảGiải quyết
POST/sign-up/emailĐăng ký người dùng mớiFR-001
POST/sign-in/emailĐăng nhập bằng emailFR-002
POST/sign-in/socialĐăng nhập mạng xã hộiFR-012
POST/sign-outĐăng xuấtFR-003
POST/refresh-tokenLàm mới tokenFR-004
POST/request-password-resetYêu cầu đặt lại mật khẩuFR-005
POST/change-passwordĐổi mật khẩuFR-007
GET/verify-emailXác minh emailFR-008
GET/list-sessionsLiệt kê các phiênFR-013
POST/revoke-sessionThu hồi phiênFR-013
POST/link-socialLiên kết tài khoản mạng xã hộiFR-012
POST/admin/set-roleĐặt vai trò người dùng cấp hệ thốngFR-011
POST/admin/ban-userCấm người dùngFR-014
POST/admin/impersonate-userGiả mạo người dùngFR-014
POST/organization/createTạo tổ chứcFR-015
POST/organization/create-roleTạo vai trò tùy chỉnh tổ chứcFR-015
POST/organization/update-roleCập nhật vai trò tổ chứcFR-015
POST/organization/delete-roleXóa vai trò tổ chứcFR-015
GET/organization/list-rolesLiệt kê các vai trò tổ chứcFR-015
GET/organization/get-roleLấy vai trò tổ chứcFR-015
POST/organization/has-permissionKiểm tra quyền tổ chứcFR-015
POST/organization/invite-memberMời thành viên (tạo token, gửi email)FR-017
GET/organization/verify-invitationXác minh token lời mời (công khai, không cần xác thực)FR-020
POST/organization/accept-invitationChấp nhận lời mời qua tokenFR-017
POST/organization/reject-invitationTừ chối lời mờiFR-017
POST/organization/resend-invitationGửi lại lời mời (token mới)FR-018
DELETE/organization/cancel-invitationThu hồi/hủy lời mời (chỉ chủ sở hữu)FR-019
POST/organization/create-teamTạo nhómFR-016

6. Luồng Tích hợp

6.1 Luồng Đăng nhập

Sơ đồ Hoạt động

Login Activity Diagram
Hình 1: Luồng Hoạt động Đăng nhập

Sơ đồ Chuỗi

Login Sequence Diagram
Hình 2: Luồng Tích hợp Đăng nhập

6.2 Luồng Đăng ký

Sơ đồ Hoạt động

Registration Activity Diagram
Hình 3: Luồng Hoạt động Đăng ký

Sơ đồ Chuỗi

Registration Sequence Diagram
Hình 4: Luồng Tích hợp Đăng ký

Chi tiết Đăng ký

Endpoint đăng ký mặc định gán vai trò hệ thống user:

Vai trò Hệ thốngMô tảTự Đăng ký
userTài khoản người dùng tiêu chuẩn (mặc định). Có thể tạo tổ chức và nhận các vai trò cấp tổ chức.Có (mặc định)
super_adminQuản trị viên hệ thống có toàn quyền truy cập.Không (chỉ tạo bởi admin qua POST /admin/create-user)

Lưu ý: Các vai trò cấp tổ chức (HR, Candidate, Employer) được định nghĩa theo từng tổ chức và gán cho thành viên thông qua hệ thống vai trò tổ chức. Chúng không phải là vai trò cấp hệ thống.

Luồng Email Xác minh qua RabbitMQ

Sau khi tạo tài khoản thành công, AUTH publish sự kiện lên RabbitMQ để gửi email xác minh. Email queue worker chạy bên trong AUTH service xử lý bất đồng bộ:

BướcThành phầnHành động
1AUTH ServiceTạo tài khoản người dùng, gán vai trò user
2AUTH ServiceGenerate mã xác minh (OTP/token), lưu vào auth_verification
3AUTH ServicePublish sự kiện verification.email.requested lên RabbitMQ (queue: verification.email)
4Email Queue Worker (AUTH)Consume sự kiện từ queue
5Email Queue Worker (AUTH)Gọi EMAIL module API để gửi email xác minh
6EMAIL ModuleGửi email qua SendGrid/SMTP, lưu log vào email_logs
7EMAIL ModuleGửi webhook callback verification.email.delivered về AUTH

Event Payload:

{
  "user_id": "uuid",
  "email": "[email protected]",
  "channel": "email",
  "otp": "123456",
  "verification_id": "ver-uuid"
}

Xử lý lỗi:

6.3 Luồng Đặt lại Mật khẩu

Sơ đồ Hoạt động

Password Reset Activity Diagram
Hình 5: Luồng Hoạt động Đặt lại Mật khẩu

Sơ đồ Chuỗi

Password Reset Sequence Diagram
Hình 6: Luồng Tích hợp Đặt lại Mật khẩu

Đặt lại Mật khẩu qua Email

Luồng đặt lại mật khẩu qua email sử dụng cùng kiến trúc event-driven với xác minh email:

BướcThành phầnHành động
1AUTH ServiceNhận yêu cầu từ POST /request-password-reset
2AUTH ServiceKiểm tra email tồn tại trong auth_users (không tiết lộ nếu email không tồn tại)
3AUTH ServiceTạo reset token, lưu hash vào auth_verification với TTL 1 giờ
4AUTH ServicePublish sự kiện password.reset.email.requested lên RabbitMQ (queue: password.reset.email)
5Email Queue Worker (AUTH)Consume sự kiện từ queue
6Email Queue Worker (AUTH)Gọi EMAIL module API để gửi email chứa liên kết đặt lại
7EMAIL ModuleGửi email qua SendGrid/SMTP, lưu log vào email_logs
8ClientUser nhấp link → GET /reset-password/{token} → Nhập mật khẩu mới
9AUTH ServiceXác minh token, cập nhật mật khẩu trong auth_users
10AUTH ServiceHủy tất cả phiên của user trong auth_sessions

Event Payload:

{
  "user_id": "uuid",
  "email": "[email protected]",
  "reset_token": "reset-token-abc",
  "expires_at": "2026-08-05T11:30:00Z",
  "verification_id": "ver-uuid"
}

Đặt lại Mật khẩu qua SMS

BướcThành phầnHành động
1AUTH ServiceNhận yêu cầu từ POST /request-password-reset với phone number
2AUTH ServiceKiểm tra SĐT tồn tại (không tiết lộ nếu SĐT không tồn tại)
3AUTH ServiceTạo mã OTP (6 chữ số), lưu vào auth_verification với TTL 5 phút
4AUTH ServicePublish sự kiện password.reset.sms.requested lên RabbitMQ (queue: password.reset.sms)
5SMS Queue Worker (AUTH)Consume sự kiện từ queue
6SMS Queue Worker (AUTH)Gọi SMS module API để gửi OTP
7SMS ModuleGửi SMS qua Twilio, lưu log vào sms_logs
8ClientUser nhập OTP + mật khẩu mới → POST /reset-password
9AUTH ServiceXác minh OTP, cập nhật mật khẩu
10AUTH ServiceHủy tất cả phiên

Xử lý lỗi:

6.4 Luồng Đăng xuất

Sơ đồ Hoạt động

Logout Activity Diagram
Hình 7: Luồng Hoạt động Đăng xuất

Sơ đồ Chuỗi

Logout Sequence Diagram
Hình 8: Luồng Tích hợp Đăng xuất

6.5 Luồng Xác minh Tài khoản

Sơ đồ Hoạt động

Verification Activity Diagram
Hình 9: Luồng Hoạt động Xác minh Tài khoản

Sơ đồ Chuỗi

Verification Sequence Diagram
Hình 10: Luồng Tích hợp Xác minh Tài khoản

6.6 Luồng Lời mời

Sơ đồ Hoạt động

Xem Phần 4.17 UC-17: Quản lý Lời mời trong SRS để xem luồng hoạt động lời mời.

Sơ đồ Chuỗi

Luồng lời mời bao gồm AUTH → EMAIL (bất đồng bộ qua RabbitMQ) → Frontend → AUTH (xác minh/chấp nhận).

  1. Admin gọi POST /organization/invite-member → AUTH tạo token, lưu hash, phát sự kiện
  2. Module EMAIL tiêu thụ sự kiện, gửi email lời mời với token gốc trong URL
  3. Người được mời nhấp liên kết → Frontend gọi GET /organization/verify-invitation?token=... (công khai)
  4. AUTH hash token, xác minh, trả về trạng thái
  5. Người được mời chấp nhận → POST /organization/accept-invitation → AUTH cập nhật trạng thái, phát sự kiện

Thiết kế Bảo mật Token

Khía cạnhTriển khai
Tạo Tokencrypto.randomBytes(32).toString('hex') — chuỗi hex 64 ký tự
Lưu trữChỉ lưu hash SHA-256 trong cột token_hash (ràng buộc UNIQUE)
Gửi điToken gốc trong URL: {FRONTEND_DOMAIN}/invitations/verify?token={rawToken}
Hết hạn72 giờ (có thể cấu hình qua INVITATION_EXPIRY_HOURS)
Gửi lạiTạo token mới, vô hiệu hóa token cũ, đặt lại thời hạn
Thu hồiChỉ chủ sở hữu; trạng thái đặt thành REVOKED; token không còn hiệu lực

Vòng đời Trạng thái Lời mời

PENDING → ACCEPTED (kết thúc)
PENDING → EXPIRED → PENDING (qua gửi lại)
PENDING → REVOKED → PENDING (qua gửi lại)

7. Thiết kế Bảo mật

Yêu cầu SRSGiải pháp Thiết kếTriển khai
NFR-003 Mã hóa mật khẩu bcrypt với 12 vòng bcrypt.hash(password, 12)
NFR-004 Thời hạn token Access ngắn hạn + refresh dài hạn Access: 15 phút, Refresh: 7 ngày
NFR-005 Giới hạn tốc độ Bộ giới hạn tốc độ dựa trên Redis 10 req/min cho các endpoint xác thực

8. Tổng kết Truy xuất nguồn gốc

Mã Yêu cầu SRSYêu cầuPhần TDSQuyết định Thiết kế
FR-001Đăng ký Người dùng3.2, 5.1, 6.2AuthController + POST /auth/register → RabbitMQ (verification.email) → Email Queue Worker → EMAIL module
FR-002Đăng nhập Người dùng2.2, 5.1Better Auth + JWT + POST /auth/login
FR-003Đăng xuất5.1POST /auth/logout (xóa phiên)
FR-004Làm mới Token2.2, 5.1JWT refresh + POST /auth/refresh
FR-005Đặt lại Mật khẩu (Email)5.1, 6.3POST /auth/forgot-password → RabbitMQ (password.reset.email) → Email Queue Worker → EMAIL module
FR-006Đặt lại Mật khẩu (Điện thoại)5.1, 6.3POST /auth/forgot-password-phone → RabbitMQ (password.reset.sms) → SMS Queue Worker → SMS module
FR-007Đổi Mật khẩu5.1POST /auth/change-password
FR-008Xác minh Email5.1GET /auth/verify-email
FR-009Xác minh Điện thoại5.1POST /auth/verify-phone
FR-010Quản lý Người dùng3.2, 5.1UsersController + GET/PUT/DELETE /users/:id
FR-011Quản lý Vai trò3.2, 5.1RolesController + POST /admin/set-role
FR-012Xác thực Mạng xã hội3.2, 5.1SocialAuthController + POST /sign-in/social
FR-013Quản lý Phiên3.2, 5.1SessionController + GET /list-sessions
FR-014Cấm & Giả mạo Người dùng3.2, 5.1SessionController + POST /admin/ban-user
FR-015Quản lý Tổ chức3.2, 5.1OrganizationsController + POST /organization/create
FR-016Quản lý Nhóm3.2, 5.1TeamsController + POST /organization/create-team
FR-017Quản lý Lời mời3.2, 5.1InvitationsController + POST /organization/invite-member
FR-018Gửi lại Lời mời3.2, 5.1InvitationsController + POST /organization/resend-invitation
FR-019Thu hồi Lời mời3.2, 5.1InvitationsController + DELETE /organization/cancel-invitation
FR-020Xác minh Token Lời mời3.2, 5.1InvitationsController + GET /organization/verify-invitation
NFR-001Đăng nhập < 500ms2.1Redis cache, DB indexing
NFR-003bcrypt 12 vòng6bcrypt.hash(password, 12)
NFR-004Thời hạn JWT6Access: 15 phút, Refresh: 7 ngày
NFR-005Giới hạn tốc độ6Redis 10 req/min