Giao diện
Chi tiết luồng xác thực Apple
Mô tả luồng form_post response mode đặc thù của Apple, cookie state, gateway middleware và xử lý user info chỉ gửi lần đầu.
Tổng quan luồng
Sign in with Apple sử dụng form_post response mode — khác với OIDC thông thường (query string), Apple POST dữ liệu qua HTML form. Plugin dùng cookie digiforce_apple cho CSRF state và gateway middleware để xử lý form POST.
Sequence diagram chi tiết
Đặc thù form_post response mode
Apple sử dụng response_mode=form_post thay vì query — đây là đặc thù quan trọng:
| Tiêu chí | form_post (Apple) | query (OIDC thông thường) |
|---|---|---|
| Cách trả về | POST form data | Query string trong URL |
| HTTP method | POST | GET |
| Bảo mật | An toàn hơn (data không nằm trong URL) | Code hiển thị trong URL/log |
| Gateway xử lý | Cần middleware đặc biệt | Đọc query string bình thường |
Gateway middleware
Vì Apple POST form data (không phải GET redirect), gateway middleware cần xử lý đặc biệt:
- Nhận POST request từ Apple
- Parse form body → extract
state - Giải mã state → xác định ứng dụng đích (
appname) - Forward toàn bộ request (bao gồm form body) đến ứng dụng tương ứng
Middleware này cần thiết vì trong kiến trúc multi-app, gateway phải biết route request đến đâu trước khi ứng dụng xử lý.
Cookie digiforce_apple
State CSRF được lưu trong cookie digiforce_apple:
| Thuộc tính | Giá trị |
|---|---|
| Name | digiforce_apple |
| Value | CSRF token (random string) |
| HttpOnly | true |
| Path | / |
Khi callback, server so sánh state trong form body với giá trị trong cookie.
User info chỉ lần đầu
Apple chỉ gửi user JSON (chứa tên) khi user authorize lần đầu tiên. Điều này có ý nghĩa:
- Lần đầu: form POST chứa
code,state, vàuser(JSON với name + email) - Các lần sau: form POST chỉ chứa
codevàstate— không cóuser
Plugin phải lưu tên user vào local account ngay lần đầu. Nếu lần đầu bị lỗi, tên user sẽ mất vĩnh viễn (trừ khi user revoke và re-authorize).
Token exchange và id_token
Sau khi nhận code, plugin exchange lấy tokens:
POST https://appleid.apple.com/auth/token
grant_type=authorization_code
code={code}
client_id={clientId}
client_secret={clientSecret}
redirect_uri={redirectUri}id_token chứa claims:
sub: Apple user ID (ổn định, không đổi giữa các lần đăng nhập)email: email user (real hoặcxxx@privaterelay.appleid.com)email_verified: luôntruevới Appleis_private_email:truenếu user chọn "Hide My Email"
Xử lý lỗi
| Lỗi | Nguyên nhân | Giải pháp |
|---|---|---|
user_cancelled_authorize | User hủy trong Apple popup | Không cần xử lý — hiển thị lại trang login |
| State mismatch | Cookie bị xóa hoặc expired | Kiểm tra cookie settings, domain |
| Invalid client | Client ID/Secret sai | Kiểm tra Apple Developer config |
| Redirect URI mismatch | APP_BASE_URL không khớp Return URL | Đồng bộ APP_BASE_URL với Apple settings |