Giao diện
Đăng nhập & phân quyền
Layer cung cấp sẵn toàn bộ luồng: trang đăng nhập, đổi credential lấy token ở IAM, giữ phiên trong cookie httpOnly, nạp quyền và chặn route. Dự án không tự viết flow đăng nhập — chỉ khai báo endpoint qua biến môi trường và khai quyền cần cho từng trang.
Luồng một lần đăng nhập
1. Người dùng vào /orders → auth.global thấy chưa đăng nhập
2. Điều hướng /auth/login?redirect=… → <TascoLoginForm>
3. Nhập tài khoản, bấm Đăng nhập → POST /auth/login (BFF, cùng origin)
4. BFF gọi IAM login-v1 → nhận access token
5. BFF gọi IAM userInfo → nhận hồ sơ + quyền
6. BFF seal cookie tasco_session → httpOnly, AES-256-GCM
7. Client nhận { user } → useState('tasco:auth:user')
8. Quay lại /orders → permission.global kiểm quyềnMật khẩu và OTP chỉ đi từ trình duyệt tới Nitro của chính app qua HTTPS. Access token không bao giờ xuống client.
Route BFF
Đây là hợp đồng cố định: đổi nhà cung cấp IAM không làm đổi các đường dẫn này.
| Route | Việc |
|---|---|
POST /auth/login | Credential → IAM login → userInfo → seal phiên, trả { user } |
GET /auth/session | Người dùng hiện tại, quyền lấy tươi từ IAM |
GET /auth/logout | Xoá cookie phiên rồi chuyển hướng |
GET /auth/clients | Danh sách ứng dụng cho dropdown trên form |
POST /auth/otp/send | Gửi OTP (Telegram) trước khi đăng nhập |
Ai chịu trách nhiệm gì
| Việc | Ai |
|---|---|
| Giao diện đăng nhập, gọi IAM, giữ phiên | Framework |
| Cơ chế kiểm quyền (route, menu, nút) | Framework |
| Cấp URL IAM, mã ứng dụng, secret phiên | Team sản phẩm (qua .env) |
| Khai quyền cần cho từng trang/nút | Team sản phẩm |
| Phát quyền cho người dùng | Quản trị IAM |
| Kiểm tra quyền trên mỗi request | Backend |
Chặn ở client không phải bảo mật
auth.global, permission.global, v-can, <Can> chỉ làm giao diện gọn gàng. Người dùng vẫn gọi API trực tiếp được. Backend phải tự kiểm tra quyền trên mọi endpoint.
Trang trong khu này
| Trang | Đọc khi |
|---|---|
| Form đăng nhập | Muốn đổi giao diện, nhãn, phương thức xác thực |
| Phiên đăng nhập | Cần hiểu cookie, thời hạn, vì sao không có refresh token |
| Cấu hình IAM | Cắm vào IAM mới hoặc backend có cấu trúc response khác |
| Mô hình phân quyền | Cần hiểu quyền URI và usePermission |
| Chặn theo quyền | Muốn ẩn/khoá route, menu, nút |
| Chạy dev không có IAM | Chưa có endpoint thật, hoặc cần chạy test |
Tra nhanh
ts
// Thông tin người dùng
const { user, isAuthenticated, logout } = useAuth()
// Kiểm tra quyền
const { can, canAll, canAny, hasRole } = usePermission()
// Trang công khai
definePageMeta({ auth: false })
// Trang cần quyền
definePageMeta({ permissions: ['/orders/search'] })vue
<CButton v-can="'/orders/create'">Tạo đơn</CButton>