Làm sao để liệt kê và revoke access token JWT

Chia sẻ
revoke access token JWT

Giả định hệ thống sử dụng JWT làm access token. Vậy làm thế nào để user có thể revoke token/session

Khi mới học backend khi làm việc với JWT đa số thường sẽ chỉ lấy userId (và một số thông tin hỗ trợ authorize) đưa vào payload. Từ đó các bạn sẽ làm một middleware verified và lấy lại phần payload này. Đây là cách đơn giản nhất để làm quen với JWT cho login và authorize.

Lý do và giải pháp JWT

Tuy nhiên, khi cần quản lý lại session của user thì phải cần thêm ít nhất một table nữa (VD: user_sessions). Có table này thì middleware (hoặc identity service) sau khi verify và lấy được payload rồi phải đi check xem record tương ứng còn hay không. Từ đó chương trình có thể quyết định xử lý request hoặc dừng lại.

ID (pk) của bảng user_sessions có thể dùng cho “tid – Token identifier” trong payload của JWT token. Từ đó verify và parse ra là có id để query tìm kiếm.

Đương nhiên về hiệu năng sẽ tăng latency rất đáng kể vì tương ứng với mỗi request đều có một query đi vào table user_sessions. Vì thế chỗ này thường sẽ triển khai thêm caching để hỗ trợ tăng tốc truy vấn. Cache này đương nhiên cũng bị invalid ngay khi user revoke hoặc hết hạn TTL (tính theo thời gian hiệu lực còn lại của token JWT).

Table session này cũng bị nhiều record theo thời gian. Vì thế cũng cần một cron/scheduler đi xoá những record đã hết hạn – với field expired_at để làm điều kiện.

Các case study khác

Một số nghiệp vụ có thể làm được với bảng user_sessions:

  1. Có thể giới hạn số lượng session đồng thời của 1 user.
  2. Có thể lưu thêm một số metadata cần thiết như: IP, Device Name, Browser Name, GEO Location…
  3. Hệ thống có thể cưỡng chế logout tất cả sessions của một user bất kỳ, hoặc khi user thực hiện đổi password.
  4. Hệ thống có thể detect trường hợp access token của user bị lấy cắp và sử dụng ở một device khác.
  5. Hệ thống có thể detect “vị trí hoặc thiết bị khác thuờng” dựa trên lịch sử đăng nhập.
  6. Và đương nhiên phía user vẫn có thể listing và revoke bất kì một session nào của họ nếu cần.

Đây là minh họa:

sequenceDiagram
    autonumber
    participant User
    participant Frontend
    participant Backend
    participant Database
    participant JWT
     
    User->>Frontend: Enter login credentials
    Frontend->>Backend: Send credentials
    Backend->>Database: Validate credentials
    Database-->>Backend: Return user data if valid
    Backend->>JWT: Generate JWT
    JWT-->>Backend: Return JWT
    Backend->>Database: Store session in session table
    Backend-->>Frontend: Return JWT
    Frontend-->>User: Store JWT

    User->>Frontend: Make a request
    Frontend->>Backend: Send request with JWT
    Backend->>JWT: Validate JWT
    JWT-->>Backend: Return validation result
    Backend->>Database: Check session in session table
    Database-->>Backend: Return session status
    Backend-->>Frontend: Return requested data if valid

    User->>Frontend: Revoke session
    Frontend->>Backend: Send revoke request with JWT
    Backend->>Database: Delete session from session table
    Database-->>Backend: Confirmation of deletion
    Backend-->>Frontend: Inform User of revocation

    Note over User, Backend: User is logged out and session is revoked.

>>Xem thêm: CRUD là gì?