1. 15:36 12/10/2026
Trong phát triển ứng dụng đa nền tảng, việc thống nhất cách đăng nhập và kiểm soát quyền truy cập là yếu tố then chốt để giảm thiểu lỗi bảo mật và tiết kiệm công sức bảo trì. Bài viết này chia sẻ quy trình thực tế để triển khai một hệ thống xác thực (Authentication) và phân quyền (Authorization) dùng OAuth2/OpenID Connect (OIDC) kết hợp JSON Web Token (JWT) cho cả React Web và React Native.
1. Chọn Identity Provider (IdP) phù hợp
- Sử dụng Keycloak, Auth0 hoặc Azure AD – tất cả đều hỗ trợ chuẩn OIDC và cung cấp endpoint descubrimiento (/.well-known/openid-configuration).
- Cấu hình client kiểu "public" cho SPA và "native" cho mobile, bật PKCE để ngăn chặn tấn công mã ủy quyền.
2. Luồng đăng nhập thống nhất
- Web: Redirect trình duyệt đến trang đăng nhập của IdP, nhận authorization code, trao đổi lấy access_token và id_token qua endpoint /token.
- Native: Mở tab trình duyệt hệ thống (ASWebAuthenticationSession trên iOS, Chrome Custom Tab trên Android) để thực hiện cùng luồng PKCE, sau đó nhận token về qua deep link.
- Lưu access_token trong bộ nhớ an toàn (SecureStore/Keychain trên mobile, httpOnly cookie hoặc memory trên web).
3. Quản lý token và refresh
- Access token ngắn hạn (5‑15 phút).
- Refresh token dài hạn, lưu trữ an toàn, tự động gọi /token khi access token hết hạn.
- Triển khai interceptor Axios/Fetch để tự động làm mới token mà không làm gián đoạn UX.
4. Phân quyền dựa trên claim trong JWT
- IdP cấp claim "roles" hoặc "permissions" trong id_token/access_token.
- Trên client, decode JWT (không verify signature vì đã tin cậy IdP) để lấy mảng quyền.
- Tạo hook `usePermission(required)` trả về boolean, dùng để render điều kiện component, route guard hoặc disable action.
5. Bảo vệ API backend
- Middleware kiểm tra signature JWT (RS256) với JWKS endpoint của IdP.
- Xác thực claim `aud`, `iss`, `exp` và quyền cần thiết cho từng endpoint.
6. Xử lý đăng xuất toàn cục (Single Logout)
- Gọi endpoint `end_session_endpoint` của IdP, xóa token cục bộ, chuyển hướng về trang đăng nhập.
- Trên mobile, xóa SecureStore và đóng webview đăng nhập.
7. Mẹo thực tế
- Tách cấu hình IdP theo environment (dev, staging, prod) bằng file `.env`.
- Viết test integration cho luồng PKCE trên cả hai nền tảng.
- Theo dõi log lỗi token expired để điều chỉnh thời gian sống token phù hợp.
Với kiến trúc này, team chỉ duy trì một bộ logic xác thực, giảm thiểu sai lệch giữa web và mobile, đồng thời tuân thủ các tiêu chuẩn bảo mật hiện đại.