+1

Spring Boot JWT, RF Token, Blacklist redis

🔐 Hướng Dẫn Xây Dựng JWT, Refresh Token và Blacklist Với Redis Trong Spring Boot

⚠️ Lưu ý: Đây là hướng tiếp cận DIY (Do-It-Yourself) phục vụ mục đích học tập, tìm hiểu, KHÔNG dùng cho thực tế. Trong môi trường thực tế, bạn nên sử dụng Authorization Server chuyên dụng như Keycloak, Auth0, hoặc các nền tảng IDaaS.

Phân biệt Authorization Server và Auth Service:

  • Authorization Server (như Keycloak, Auth0) thường là hệ thống độc lập, chuyên việc quản lý danh tính, cấp token cho nhiều ứng dụng, client khác (thích hợp cho các sản phẩm SaaS, microservices).
  • Auth Service: hay viết thủ công là phần xử lý xác thực/uỷ quyền tích hợp trực tiếp vào 1 ứng dụng cụ thể. Phù hợp cho ứng dụng nội bộ hoặc không yêu cầu tích hợp với bên thứ 3.

Ứng Dụng Này Làm Gì?

  • Đăng ký, đăng nhập người dùng
  • Sinh ra accessTokenrefreshToken
  • Cho phép lấy access token mới qua refresh token
  • Cho phép logout và thực hiện blacklist access token
  • Bảo vệ các API bằng JWT
  • Sử dụng Redis để lưu blacklist token với TTL tương ứng

⚙️ Cơ Chế Blacklist Hoạt Động Thế Nào?

  1. Khi logout, ta sẽ:

    • Xoá refreshToken khỏi database để vô hiệu hoá hoàn toàn session đó (session nghĩa là phiên).
    • Cho accessToken vào Redis blacklist kèm TTL (time-to-live)
  2. Nếu access token bị nằm trong danh sách blacklist → từ chối truy cập

  3. Nếu 1 token hết hạn theo thời gian hoặc nằm trong blacklist thì yêu cầu truy cập bị từ chối.


DB Shema

refresh_tokens.png

  • refresh_tokens table: lưu refresh token cho từng user (dễ revoke thủ công hoặc theo session)
  • Redis: lưu access token bị revoke (dạng String key-value, TTL = thời gian còn lại đến hết hạn)

🔑 Các API Chính

Các API chính cung cấp để quản lý xác thực và truy cập tài nguyên.

Auth API

Endpoint Method Chức năng
/api/auth/register POST Đăng ký tài khoản mới
/api/auth/login POST Đăng nhập
/api/auth/refresh-token POST Lấy access token mới
/api/auth/logout POST Logout, thu hồi token

Secure API (Yêu cầu JWT)

Header: Authorization: Bearer <access_token>

Endpoint Method Chức năng
/api/user GET Truy cập user content
/api/admin GET Truy cập admin content
/api/demo GET API test lỗi 404

💻 Thử Nghiệm Với Postman

Lệnh Clone:

git clone --filter=blob:none --no-checkout https://github.com/thnhan1/spring-security6.git
cd spring-security6
git sparse-checkout init --cone
git sparse-checkout set jwt-rf-blacklist

🔄 Ví Dụ Response Đăng Nhập

{
    "accessToken": "eyJhbGciOiJIUzI1NiJ9...",
    "tokenType": "Bearer",
    "expiresAt": "2025-07-09T02:10:40.394009100Z",
    "refreshToken": "d2dc2e5c-40b5-4754-8df7-ce386206acb1"
}

❓ Câu Hỏi Thường Gặp

Câu 1: Sau khi refresh token, access token cũ còn dùng được không?

Có. Chỉ khi nào logout thì token mới bị revoke thông qua blacklist. Ngoài ra, access token sẽ có hiệu lực cho đến khi hết hạn.


Câu 2: Nếu user đổi role thì token cũ vẫn còn giá trị?

Còn JWT không truy vấn database mỗi lần request. Do đó:

  • Nếu cần cập nhật quyền, FE nên gọi /refresh-token để lấy token mới chứa role cập nhật

  • Nếu cần mạnh tay hơn, backend có thể revoke các token hiện tại hoặc dùng phiên bản token (tokenVersion) để vô hiệu hóa toàn bộ


Câu 3: Refresh token lưu ở đâu?

Trong hướng dẫn này, refreshToken được lưu trong database (có thể là PostgreSQL, MySQL...). Bạn cũng có thể lưu vào Redis hoặc kết hợp với device/session ID.


4. Blacklist token trong Redis lưu thế nào?

  • Key: blacklisted:<access_token>
  • Value: "true" hoặc rỗng
  • TTL: tính bằng thời điểm logout - lúc token hết hạn của token.

Lời khuyên:

🔒 Trong thực tế, để đảm bảo bảo mật, hiệu xuất và khả năng mở rộng, bạn nên dùng:

  • Supabase: Phù hợp với ứng dụng Node.js, có gói Free plan.

  • Firebase Auth: Dễ sử dụng cho mobile, nhưng khả năng tùy chỉnh vai trò (custom roles) có thể không linh hoạt bằng các giải pháp khác. (Locket, Bách hoá xanh App tích điểm dùng).

  • Keycloak: Một Authorization Server mã nguồn mở, mạnh mẽ và rất linh hoạt, nhưng có thể hơi phức tạp để cấu hình cho các ứng dụng nhỏ.

  • Auth0: Một nền tảng quản lý danh tính (IDaaS) phổ biến với nhiều tài liệu hướng dẫn, nhưng chi phí có thể tăng khi số lượng người dùng lớn. (Ví dụ: ChatGPT dùng Auth0).

  • OAuth2 Authorization Server của Spring: Một dự án của Spring để xây dựng Authorization Server tuân thủ OAuth 2.0.

  • Giải pháp Tự xây dựng (In-House): Các công ty lớn với yêu cầu bảo mật và tùy chỉnh cực cao thường tự xây dựng giải pháp xác thực của riêng mình.

Câu hỏi cho bạn

Cái app api này là Auth Server hay Auth Serice?

-> Auth Service.

Vậy nói Auth Server ở lời khuyên làm gì. Lạc đề à?

-> Không vì ứng dụng web muốn kiếm nhiều tiền thì phải cho các bên thứ 3 chơi chung chứ chơi 1 mình vậy sao có nhiều tiền. (trừ khi bạn quá bá đạo).

Auth Service cho user đăng ký user rồi đẩy data qua Auth Server hả?

-> Không Auth Service có api và thường có UI riêng nên không có chuyện đẩy kiểu đó. Nói nữa lạc đề thật.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí