Back to docs hub
Auth & User

Auth flow map cho Threads API v2

Trang này ghi lại luồng vận hành thật của module auth hiện tại: token được tạo ở đâu, refresh token được lưu và rotate ra sao, middleware chặn request thế nào, email verification/reset password đi qua queue nào. Swagger vẫn là nguồn cho payload chi tiết; tài liệu này tập trung vào flow và dependency.

access token payload
subuser.id
sidsessionId
statusUserStatus
ttlACCESS_EXPIRES
01

System Map

Auth hiện tại chia thành ba lớp: HTTP route/controller, domain service/repository, và hạ tầng token/Redis/queue.

HTTP boundary

auth.routesvalidateauth.controller

Routes validate body/query bằng Zod trước, controller lấy IP/user-agent rồi gọi service. Các route cần phiên dùng middleware authorization.

Domain core

auth.serviceauth.repositoryverification.repository

Service xử lý register/login/refresh/logout/email/reset. Repository bọc Prisma cho users, refresh_tokens, verification_codes.

Infrastructure

jwt.serviceRedisBullMQNodemailer

JWT ký access token, refresh token là random hex được hash SHA-256 trước khi lưu DB. Redis giữ blacklist và Bloom filter, queue xử lý email/Bloom async.

02

Auth Flow Chart

Flow chart này gom toàn bộ auth module theo lớp chạy thật: client đi vào route/controller, request cần quyền đi qua guard, service xử lý session/token, state nằm ở MySQL/Redis, còn email và Bloom filter chạy qua BullMQ worker.

Threads API v2 auth flow chart Flow chart mô tả route auth, middleware authorization, AuthService, Prisma database, Redis, BullMQ email worker và Bloom worker. Client / route entry Controller / middleware AuthService core State storage Async workers Client request Swagger / app / web Zod validate body, params, query Route? public or protected JSON response token pair / user / status Protected route Authorization: Bearer Blacklist check Redis bl:at:<token> Verify JWT JWT_SECRET + sub Load user status != BANNED Attach context req.user + accessToken Unauthorized / Forbidden Auth endpoints register, login, verify Password + token bcrypt, jwtService Refresh rotate revoke old, create new Logout revoke access blacklist + refresh Email token flow resend, forgot, reset users email, username, status refresh_tokens sha256 token + session verification_codes VERIFY / FORGOT hash Redis blacklist + Bloom data BullMQ queues emailQueue, bloomQueue Generate Bloom job after register Bloom worker BF.ADD username/email Redis Bloom validate availability Email worker EJS template render SMTP delivery verify / reset link
AuthService / token logic MySQL, Redis, BullMQ state Worker xử lý nền Đường nét đứt là async hoặc nhánh lỗi
03

Session Lifecycle

Đây là đường đi chính từ lúc tạo tài khoản tới khi refresh/logout. Tài liệu cố ý không ghi payload chi tiết vì Swagger đã cover phần đó.

Register
  1. Zod validate username, email, password, confirm password.
  2. Password được hash bằng bcrypt.hashSync(password, 10).
  3. Tạo user mới trong users với email, username, password.
  4. jwtService.generateTokenPair tạo access token và refresh token.
  5. Refresh token được hash SHA-256 rồi lưu vào refresh_tokens cùng sessionId, IP, user-agent, expireAt.
  6. Đẩy job thêm username/email vào Redis Bloom filter.
ResultClient nhận user summary, accessToken, refreshToken, sessionId. Email verify chưa tự gửi trong register flow hiện tại.
Login
  1. Login field có thể là email hoặc username.
  2. Repository tìm user bằng OR email/username.
  3. Password được so bằng bcrypt.compareSync.
  4. Nếu hợp lệ, tạo token pair mới và lưu refresh token hash vào DB.
ResultSai user/password trả về invalid credentials ở controller; đúng thì tạo một session mới.
Refresh
  1. Client gửi refresh token hiện tại.
  2. Service hash token rồi tìm trong refresh_tokens.token.
  3. Nếu token không tồn tại, đã revoke, hoặc hết hạn thì trả invalid.
  4. Token cũ bị revoke bằng revokedAt = now.
  5. Tạo access/refresh mới, giữ cùng sessionId, lưu refresh token mới đã hash.
ResultRefresh token rotation: mỗi lần refresh làm token cũ hết hiệu lực và sinh token mới.
Logout
  1. Middleware auth lấy access token hiện tại từ header và gắn vào req.accessToken.
  2. Service set Redis key bl:at:<accessToken> với TTL 15 phút.
  3. Refresh token trong body được hash, tìm trong DB, nếu có thì revoke.
ResultAccess token bị chặn bởi blacklist cho tới khi TTL hết; refresh token bị revoke trong DB.
04

Protected Request Guard

Mọi route dùng middleware authorization đi qua cùng một cửa kiểm tra.

1 header
Parse bearer

Đọc Authorization, lấy phần sau dấu cách. Thiếu token thì Unauthorized.

2 redis
Blacklist check

Kiểm tra bl:at:<token>. Nếu tồn tại, token bị coi là invalid.

3 jwt
Verify signature

jwt.verify bằng JWT_SECRET, payload cần có sub.

4 db
Load user

Tìm user theo sub. Không có user thì invalid token.

5 attach
Request context

Nếu user không bị BANNED, gắn req.userreq.accessToken.

05

Email Verification & Password Recovery

Hai luồng email dùng cùng pattern: sinh token random, hash token lưu DB, gửi token raw qua email worker.

Verify email

  • Route resend verify yêu cầu access token hợp lệ.
  • Service sinh token 32 bytes hex, hash SHA-256 rồi lưu vào verification_codes với type VERIFY_ACCOUNT.
  • Job SEND_VERIFICATION_EMAIL render template/verify-email.ejs và gửi link /verify-email?token=....
  • Verify email nhận token, hash lại, tìm record đúng type, kiểm tra expiresAt, rồi set users.verified_at = now.

Forgot/reset password

  • Forgot password tìm user theo email; không thấy thì NotFound.
  • Nếu có user, tạo token, lưu hash với type FORGOT_PASSWORD, gửi email reset qua queue.
  • Email worker render template/forgot-password.ejs và gửi link /reset-password?token=....
  • Reset password hash token, tìm record type forgot password, kiểm tra expiry, tìm user theo email, so confirm password, hash password mới rồi update DB.
06

Email/Username Availability

Validate email/username hiện đọc Redis Bloom filter thay vì query trực tiếp database.

register
Create user

User được tạo trong DB trước.

queue
Bloom job

Register enqueue job GENERATE_BLOOM.

worker
Redis BF.ADD

Worker thêm username vào filter:usernames và email vào filter:emails.

validate
Redis BF.EXISTS

Validate trả available = !exists.

tradeoff
Fast but approximate

Bloom filter nhanh, nhưng về bản chất có thể false positive.

07

State, Storage & Observations

Các điểm dưới đây là mô tả hiện trạng để team nắm rõ. Tài liệu không sửa behavior.

users
id, email, username, password
verified_at, status
profile fields
created_at, updated_at
refresh_tokens
token = sha256(raw refresh)
session_id
expire_at
revoked_at
ip, user_agent
verification_codes
token_hash = sha256(raw token)
type = VERIFY_ACCOUNT | FORGOT_PASSWORD
expires_at
used_at currently not updated
current behavior

register tạo token pair và enqueue Bloom job, nhưng không tự gửi verification email. Verification email hiện đi qua route resend.

current behavior

updateProfile hiện trả { updated: true } theo input, chưa persist profile xuống database.

current behavior

validateResetPasswordToken hiện luôn trả { valid: true }, chưa kiểm tra verification_codes.

current behavior

Verification code expiry đang dùng ACCESS_EXPIRES khi lưu DB; text hiển thị trong email dùng config riêng cho verify/reset.

current behavior

Middleware auth chỉ block rõ trạng thái BANNED. Các trạng thái khác như SUSPENDED hoặc DEACTIVATED chưa có nhánh xử lý riêng trong guard.

current behavior

jwtService.requestAuthToken dùng cho optional auth verify JWT trực tiếp, không kiểm Redis blacklist như middleware authorization.