Authentication
Google OAuth 2.0 + JWT flow
Luồng đăng nhập
1. User bấm "Đăng nhập với Google"
2. Google One Tap popup → user chọn account
3. Google trả về ID Token
4. Frontend: POST /steadii/auth/google { idToken }
5. Backend verify với Google → tạo/cập nhật user
6. Backend ký JWT (RS256) → trả về
7. Frontend lưu JWT vào memory (KHÔNG localStorage)
8. fullSync() tự động chạyJWT Token
- Thuật toán: RS256 (private key ký, public key verify)
- Payload:
{ sub: userId, email, name } - Thời hạn: 7 ngày
- Lưu trữ: Memory only — reload = phải đăng nhập lại
JWT không lưu vào localStorage để tránh rủi ro XSS. Google One Tap thường tự re-auth nhanh.
sendBeacon Auth
Khi đóng tab, sendBeacon() không set được headers nên JWT được gửi trong body:
{ "_token": "<JWT>", "habits": [...], ... }Backend authMiddleware kiểm tra cả Authorization header lẫn _token trong body.