Bỏ qua để đến nội dung
Knowledge Hub

Sắp xếp: một lần đăng nhập OAuth Authorization Code + PKCE đúng chuẩn Trung cấp

Thời gian đọc ước tính: 1 phút

Mỗi bước của một lần đăng nhập Authorization Code + PKCE tồn tại để chặn một kiểu tấn công cụ thể. Làm sớm một bước hoặc bỏ nó đi, và một code bị lấy cắp, một callback bị cài sẵn hay một token sai audience sẽ lọt qua.

Sắp xếp các bước dưới đây, từ cú bấm Đăng nhập tới lúc orders API trả 200. Bấm Kiểm tra để biết bước nào sai chỗ và sai thì hỏng gì.

Sắp xếp

Đăng nhập qua IdP rồi gọi orders API, theo đúng thứ tự

SPA của shop có một backend-for-frontend (BFF) đăng ký ở id.shop.example với client_id = shop-web và redirect URI https://shop.example/auth/callback. Người dùng bấm Đăng nhập, rồi mở "Đơn hàng của tôi", trang này gọi orders API viết bằng NestJS ở api.shop.example.

Sắp xếp các bước của một lần đăng nhập Authorization Code + PKCE đúng chuẩn, từ cú bấm tới lúc API trả 200.

Dùng ▲▼ để đổi chỗ từng bước, hoặc chạm ⠿ của một bước rồi chạm vào vị trí mới. Trên máy tính có thể kéo thả.

  1. Orders API chọn key theo kid từ JWKS của IdP, kiểm chữ ký, typ = at+jwt, iss, aud, exp, rồi kiểm sub có sở hữu đơn hàng không
  2. BFF sinh ngẫu nhiên code_verifier (32 byte), state và nonce, lưu vào session tạm trước login
  3. Ở /auth/callback, so state (và iss) với giá trị đã lưu rồi huỷ chúng; không khớp thì dừng
  4. Kiểm ID token (chữ ký, iss, aud = shop-web, exp, nonce), rồi tạo session mới và set cookie __Host- HttpOnly
  5. SPA gọi BFF bằng cookie; BFF chuyển request kèm Authorization: Bearer <access_token>
  6. Người dùng đăng nhập ở IdP (system browser, không phải WebView nhúng); IdP cấp code ngắn hạn, dùng một lần, gắn với challenge
  7. BFF POST tới /token qua back channel: code, code_verifier, cùng redirect_uri, và client credentials của nó
  8. Redirect browser tới /authorize kèm code_challenge = S256(verifier), code_challenge_method=S256, state, nonce và đúng redirect_uri đã đăng ký

Chi tiết về luồng, nơi lưu token và cách API kiểm token: OAuth 2.0, OIDC và PKCE.