Luồng xác thực (Authentication Flow)
Client Integration Guide - Authentication Flow
Phần tiêu đề “Client Integration Guide - Authentication Flow”Tài liệu này mô tả luồng gọi API theo quy chuẩn BPMN Identity Flow. Nguồn chuẩn cho hành vi là tài liệu đó và proto/auth/ (attestation, authentication), proto/justo/identity/ (đăng ký, đăng nhập, social). Khi các nguồn này đổi, tài liệu phải được cập nhật theo.
1. Tổng quan
Phần tiêu đề “1. Tổng quan”Mọi API dùng JSON với field camelCase. Mỗi response có dạng:
{ "code": 0, "message": "", "payload": { } }code = 0là thành công. Mã lỗi xem tại Mã lỗi.- Mọi bước sau
init-sessioncần headerX-Api-Session-Idvới session ID được cấp ở bước này. - Các bước đăng ký và đăng nhập trả về
nextStep(enumStep). Client phải gọi đúng endpoint tương ứng vớinextStep, không tự suy đoán thứ tự.
| Nhóm | Endpoint | Mục đích |
|---|---|---|
| Thiết bị | GET /v1/attestation/get-challenge |
Lấy challengeJwt (chỉ iOS) |
| Phiên | POST /v1/auth/init-session |
Trao đổi khóa, tạo session |
| Email và phone | verify-email, verify-otp-email, verify-phone, verify-otp-phone |
Xác minh email và số điện thoại |
| Đăng ký | register, register-basic-info, create-pin-code |
Tạo tài khoản mới |
| Đăng nhập | verify-password |
Xác thực mật khẩu |
| Social | social/nonce, social-login |
Đăng nhập Google hoặc Apple |
| Đăng xuất | logout |
Kết thúc session |
2. Lấy challenge (chỉ iOS)
Phần tiêu đề “2. Lấy challenge (chỉ iOS)”GET /v1/attestation/get-challenge trả về payload.challengeJwt, hết hạn sau 5 phút. Gửi giá trị này trong attestation.challengeJwt khi gọi init-session.
Android không cần bước này và gửi attestation.androidToken.
3. Khởi tạo session
Phần tiêu đề “3. Khởi tạo session”POST /v1/auth/init-session
| Field | Bắt buộc | Ghi chú |
|---|---|---|
userId |
Không | Hex. Để trống với luồng chưa có người dùng |
clientJwtCert |
Có | Khóa công khai P-256 (JWK) cho factor JWT |
clientSensitiveJwtCert |
Có | Chứng chỉ JWT cho dữ liệu nhạy cảm |
clientP256Cert |
Có | Khóa công khai P-256 cho ECDH, kèm salt 32 byte |
attestation |
Có | platform là IOS hoặc ANDROID, kèm các field tương ứng |
Với IOS, attestation cần challengeJwt, xKeyId và xChallengeResponse. Với ANDROID, cần androidToken. deviceUuid dài 1 đến 32 ký tự.
payload.jwtToken là JWT ký Ed25519 bằng preshare key. Claim sessionId là giá trị dùng cho header X-Api-Session-Id. Claim publicKey là khóa ECDH của server (65 byte, P-256 không nén). Claim salt là ciphertext AES-256-GCM (60 byte, gồm nonce, ciphertext và tag).
4. Các luồng theo nextStep
Phần tiêu đề “4. Các luồng theo nextStep”Bước đầu tiên của mọi luồng là verify-email. Kết quả phụ thuộc vào loại tài khoản của email:
| Email thuộc về | nextStep sau verify-email |
Luồng |
|---|---|---|
| Chưa có tài khoản | STEP_VERIFY_EMAIL_OTP (kèm otpId) |
4.1 Đăng ký mới |
| Tài khoản Justo hiện hữu | STEP_VERIFY_PHONE (kèm phone đã che) |
4.2 Đăng nhập |
| Tài khoản Ecommerce cũ | STEP_OLD_PASSWORD |
4.3 Di chuyển tài khoản cũ |
Luôn đọc nextStep từ payload trước khi gọi bước tiếp theo.
4.1 Đăng ký tài khoản mới
Phần tiêu đề “4.1 Đăng ký tài khoản mới”| Bước | Endpoint | Body | nextStep trả về |
|---|---|---|---|
| 1 | POST /v1/auth/verify-email |
email |
STEP_VERIFY_EMAIL_OTP, kèm otpId (hết hạn sau 5 phút) |
| 2 | POST /v1/auth/verify-otp-email |
otpId, otp |
STEP_VERIFY_PHONE |
| 3 | POST /v1/auth/verify-phone |
phone (E.164) |
STEP_VERIFY_PHONE_OTP, kèm otpId. Trả lỗi 2021 nếu số đã thuộc tài khoản khác |
| 4 | POST /v1/auth/verify-otp-phone |
otpId, otp |
STEP_CREATE_ACCOUNT |
| 5 | POST /v1/auth/register |
password (8 đến 256 ký tự) |
STEP_BASIC_INFO |
| 6 | POST /v1/auth/register-basic-info |
givenName, paternalSurname, maternalSurname, dateOfBirth (YYYY-MM-DD), gender |
Dưới 18 tuổi: STEP_COMPLETED (tài khoản Level 1). Từ 18 tuổi: STEP_CREATE_PIN_CODE |
| 7 | POST /v1/auth/create-pin-code |
pinCode |
STEP_COMPLETED (tài khoản Level 2). Chỉ áp dụng khi bước 6 trả STEP_CREATE_PIN_CODE |
4.2 Đăng nhập tài khoản Justo hiện hữu
Phần tiêu đề “4.2 Đăng nhập tài khoản Justo hiện hữu”Trên thiết bị mới hoặc chưa tin cậy, OTP số điện thoại được xác thực trước, mật khẩu xác thực sau.
| Bước | Endpoint | Body | nextStep trả về |
|---|---|---|---|
| 1 | POST /v1/auth/verify-email |
email |
STEP_VERIFY_PHONE, kèm phone đã che |
| 2 | POST /v1/auth/verify-phone |
phone |
STEP_VERIFY_PHONE_OTP, kèm otpId |
| 3 | POST /v1/auth/verify-otp-phone |
otpId, otp |
STEP_LOGIN_PASSWORD |
| 4 | POST /v1/auth/verify-password |
password |
STEP_CREATE_PIN_CODE (Level 2, cần nhập PIN) hoặc STEP_COMPLETED (Level 1) |
4.3 Di chuyển tài khoản Ecommerce cũ
Phần tiêu đề “4.3 Di chuyển tài khoản Ecommerce cũ”Áp dụng cho người đã có tài khoản Ecommerce nhưng chưa có tài khoản Justo.
| Bước | Endpoint | Body | nextStep trả về |
|---|---|---|---|
| 1 | POST /v1/auth/verify-email |
email |
STEP_OLD_PASSWORD |
| 2 | POST /v1/auth/verify-password |
password (mật khẩu Ecommerce cũ) |
STEP_VERIFY_PHONE, kèm phone của tài khoản cũ để FE tự điền |
| 3 | POST /v1/auth/verify-phone |
phone (đã được tự điền) |
STEP_VERIFY_PHONE_OTP, kèm otpId |
| 4 | POST /v1/auth/verify-otp-phone |
otpId, otp |
STEP_CREATE_PIN_CODE nếu đã có thông tin cơ bản, ngược lại STEP_BASIC_INFO |
Sau bước 4, tài khoản Justo Level 1 được kích hoạt. Từ đây, luồng tiếp tục giống bước 6 và 7 của mục 4.1.
4.4 Đăng nhập qua Google hoặc Apple
Phần tiêu đề “4.4 Đăng nhập qua Google hoặc Apple”POST /v1/auth/social/nonce(không có body). Trả vềnoncevàexpiresAt. Nonce hết hạn sau 10 phút và chỉ dùng được một lần.- Client lấy
idTokentừ nhà cung cấp. POST /v1/auth/social-loginvớiprovidervàidToken. Payload trả vềid,displayName,phonevànextStep.- Tài khoản social mới:
STEP_VERIFY_PHONE. Social không cần tạo mật khẩu. - Tài khoản đã liên kết Justo: theo cấp độ,
STEP_COMPLETEDhoặcSTEP_CREATE_PIN_CODE.
- Tài khoản social mới:
Chi tiết các trường hợp biên xem Kiến trúc đăng nhập Google / Apple.
4.5 Đăng xuất
Phần tiêu đề “4.5 Đăng xuất”POST /v1/auth/logout với header X-Api-Session-Id. Sau khi thành công, session không còn dùng được.
5. Ý nghĩa các giá trị nextStep
Phần tiêu đề “5. Ý nghĩa các giá trị nextStep”| Giá trị | Ý nghĩa |
|---|---|
STEP_VERIFY_EMAIL_OTP |
Nhập OTP gửi tới email |
STEP_VERIFY_PHONE |
Xác nhận số điện thoại để gửi OTP |
STEP_VERIFY_PHONE_OTP |
Nhập OTP gửi tới số điện thoại |
STEP_CREATE_ACCOUNT |
Đã xác minh email và phone, cần tạo mật khẩu |
STEP_BASIC_INFO |
Nhập thông tin cá nhân |
STEP_CREATE_PIN_CODE |
Tạo hoặc nhập mã PIN |
STEP_LOGIN_PASSWORD |
Nhập mật khẩu Justo để đăng nhập |
STEP_OLD_PASSWORD |
Tài khoản Ecommerce cũ, nhập mật khẩu cũ |
STEP_COMPLETED |
Hoàn tất |
6. Thời hạn và lỗi thường gặp
Phần tiêu đề “6. Thời hạn và lỗi thường gặp”- Trạng thái luồng (
nextStep) được gia hạn 15 phút sau mỗi lần gọi thành công. Nếu chờ quá lâu, session hết hạn và client phải gọi lạiinit-session. - Session sau khi đăng nhập hoặc đăng ký có hiệu lực 30 ngày.
- OTP email và OTP phone hết hạn sau 5 phút. OTP hết hạn trả lỗi
2017. Nhập sai quá số lần cho phép trả lỗi2018. - Gọi sai thứ tự (ví dụ
registerkhinextStepkhông phảiSTEP_CREATE_ACCOUNT) trả lỗi2003.
Danh sách đầy đủ mã lỗi xem tại Mã lỗi.
7. Bảo mật
Phần tiêu đề “7. Bảo mật”- Chỉ gửi khóa công khai. Khóa riêng không rời khỏi thiết bị.
- Kiểm tra chữ ký và thời hạn của
jwtTokentrước khi dùngsessionId. - Không lưu mật khẩu, PIN hoặc OTP trên thiết bị.
Xem thêm Bảo mật.