Skip to content

Đă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ền

Mậ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.

RouteViệc
POST /auth/loginCredential → IAM login → userInfo → seal phiên, trả { user }
GET /auth/sessionNgười dùng hiện tại, quyền lấy tươi từ IAM
GET /auth/logoutXoá cookie phiên rồi chuyển hướng
GET /auth/clientsDanh sách ứng dụng cho dropdown trên form
POST /auth/otp/sendGửi OTP (Telegram) trước khi đăng nhập

Ai chịu trách nhiệm gì

ViệcAi
Giao diện đăng nhập, gọi IAM, giữ phiênFramework
Cơ chế kiểm quyền (route, menu, nút)Framework
Cấp URL IAM, mã ứng dụng, secret phiênTeam sản phẩm (qua .env)
Khai quyền cần cho từng trang/nútTeam sản phẩm
Phát quyền cho người dùngQuản trị IAM
Kiểm tra quyền trên mỗi requestBackend

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ậpMuốn đổi giao diện, nhãn, phương thức xác thực
Phiên đăng nhậpCần hiểu cookie, thời hạn, vì sao không có refresh token
Cấu hình IAMCắm vào IAM mới hoặc backend có cấu trúc response khác
Mô hình phân quyềnCần hiểu quyền URI và usePermission
Chặn theo quyềnMuốn ẩn/khoá route, menu, nút
Chạy dev không có IAMChư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>