Session Token trong phát triển ứng dụng — nó là gì, nguyên lý hoạt động và sự khác biệt với JWT

Tác giả: IT Sectr Đã đăng: 2026-04-05 Thời gian đọc: 9 phút

Session Token là một định danh duy nhất mà máy chủ tạo ra sau khi xác thực người dùng thành công và sử dụng để nhận dạng các yêu cầu tiếp theo. Không giống như các token tự chứa (JWT), session token là một chuỗi ngẫu nhiên tự nó không chứa dữ liệu: tất cả thông tin phiên làm việc được lưu trữ trên máy chủ trong RAM hoặc cơ sở dữ liệu. Theo OAuth.com, 2025, session token vẫn là cơ chế xác thực phổ biến nhất trong các ứng dụng web phía máy chủ và kiến trúc di động lai.

Những điểm chính

  • Session Token — một định danh ngẫu nhiên tham chiếu đến dữ liệu phiên phía máy chủ
  • Stateful — máy chủ lưu trạng thái phiên trong Redis, Memcached hoặc cơ sở dữ liệu
  • Thu hồi đơn giản — chỉ cần xóa bản ghi phiên trên máy chủ, token sẽ trở thành không hợp lệ
  • Bảo mật — dữ liệu không được lưu trong token, loại trừ rò rỉ qua giải mã
  • Cookie — cách truyền thống để gửi session token trong các ứng dụng web với các cờ HttpOnly, Secure và SameSite

Session Token là gì?

Session Token (định danh phiên) là một chuỗi duy nhất mà máy chủ tạo ra và liên kết với dữ liệu phiên sau khi xác thực người dùng. Token không chứa bất kỳ thông tin người dùng nào — nó chỉ là một khóa để truy cập dữ liệu được lưu trên máy chủ. Cách tiếp cận này được gọi là xác thực stateful: máy chủ lưu trạng thái của mỗi phiên hoạt động và kiểm tra nó ở mỗi yêu cầu.

Dữ liệu phiên bao gồm: ID người dùng, thời gian đăng nhập, địa chỉ IP, user-agent, danh sách quyền, thời gian hoạt động cuối cùng. Khi client gửi yêu cầu với session token, máy chủ tìm bản ghi tương ứng trong kho lưu trữ phiên, kiểm tra tính hợp lệ của nó và truy xuất dữ liệu để xử lý yêu cầu. Nếu bản ghi phiên không tồn tại hoặc đã hết hạn, máy chủ trả về lỗi xác thực và yêu cầu đăng nhập lại.

Theo OWASP, 2025, session token vẫn là tiêu chuẩn cho các ứng dụng yêu cầu thu hồi quyền truy cập ngay lập tức — ví dụ, trong các hệ thống ngân hàng và cổng thông tin doanh nghiệp nơi quản trị viên phải có khả năng kết thúc phiên làm việc của người dùng ngay lập tức. Trong các hệ thống này, session token cung cấp khả năng kiểm soát truy cập hoàn toàn mà không thể đạt được với các token stateless nếu không có cơ chế chặn bổ sung.

Cách hoạt động của Session Token

Quá trình bắt đầu khi client gửi thông tin đăng nhập đến máy chủ xác thực. Máy chủ xác minh tên đăng nhập và mật khẩu, tạo bản ghi phiên trong kho lưu trữ (thường là Redis hoặc cơ sở dữ liệu) và trả về một session token duy nhất cho client. Client lưu token và gửi nó với mỗi yêu cầu tiếp theo, và máy chủ kiểm tra sự tồn tại và tính hợp lệ của phiên mỗi lần.

Phiên máy chủ và lưu trữ

Redis là kho lưu trữ phiên phổ biến nhất nhờ lưu trữ trong bộ nhớ và hỗ trợ TTL (thời gian sống). Mỗi phiên được lưu dưới dạng cặp khóa-giá trị, trong đó khóa là session token và giá trị là một đối tượng JSON chứa dữ liệu phiên. TTL tự động xóa các phiên đã hết hạn. Các lựa chọn thay thế: Memcached (chỉ bộ nhớ, không lưu trữ trên đĩa), PostgreSQL/MySQL (bền vững nhưng chậm hơn) và DynamoDB (cho cơ sở hạ tầng AWS).

Ví dụ về cấu trúc phiên trong Redis: session:{token}{“userId”: 42, “role”: “admin”, “createdAt”: 1812345678, “lastAccess”: 1812345678}. Máy chủ cập nhật lastAccess ở mỗi yêu cầu, cho phép triển khai thời gian chờ không hoạt động — tự động kết thúc phiên sau một khoảng thời gian không hoạt động.

Cookie so với Header

Session Token có thể được truyền theo hai cách: qua cookie HTTP hoặc qua header HTTP Authorization. Cookie là cách truyền thống cho các ứng dụng web: máy chủ đặt cookie với các cờ HttpOnly (không thể truy cập từ JavaScript), Secure (chỉ HTTPS) và SameSite (bảo vệ CSRF). Đối với ứng dụng di động, header Authorization: Bearer <session_token> thường được sử dụng hơn, vì cơ chế cookie không phải lúc nào cũng thuận tiện trong client gốc.

Vòng đời của Session Token

Vòng đời của session token bao gồm ba giai đoạn: tạo, duy trì phiên hoạt động và kết thúc. Mỗi giai đoạn yêu cầu cấu hình bảo mật phù hợp để ngăn chặn rò rỉ hoặc chặn token.

Tạo, lưu trữ và xóa

Tạo — máy chủ tạo một chuỗi ngẫu nhiên an toàn mật mã hóa dài 128–256 bit (ví dụ, qua SecureRandom trong Java hoặc os.urandom trong Python). Token phải không thể đoán trước — việc sử dụng UUID hoặc dấu thời gian mà không có entropy là không thể chấp nhận. Lưu trữ trên client: trên iOS — Keychain, trên Android — EncryptedSharedPreferences, trên web — cookie HttpOnly. Xóa xảy ra khi đăng xuất: client xóa token khỏi kho lưu trữ, máy chủ xóa bản ghi phiên khỏi Redis. Sau khi đăng xuất, session token trở nên vô dụng — máy chủ sẽ không tìm thấy bản ghi tương ứng.

Theo SANS Institute, 2025, việc triển khai đúng cách kết thúc phiên (đăng xuất với dọn dẹp phía máy chủ) ngăn chặn tới 70% các cuộc tấn công sử dụng token bị đánh cắp. Điều quan trọng là không chỉ xóa token trên client mà còn vô hiệu hóa phiên trên máy chủ.

Session Token so với JWT

Session Token và JWT đại diện cho hai cách tiếp cận xác thực khác nhau. Session Token là stateful (máy chủ lưu trạng thái), JWT là stateless (dữ liệu bên trong token). Việc lựa chọn giữa chúng phụ thuộc vào kiến trúc ứng dụng và yêu cầu bảo mật.

Tiêu chíSession TokenJWT
Mô hìnhStateful (dữ liệu trên máy chủ)Stateless (dữ liệu trong token)
Thu hồiTức thì — xóa phiên khỏi RedisCần danh sách đen hoặc TTL ngắn
Kích thước16–64 byte500–2000 byte
Lưu trữ dữ liệuChỉ trên máy chủ (an toàn)Bên trong token (base64, không mã hóa)
Mở rộngCần lưu trữ dùng chung (Redis)Không cần — token được xác thực cục bộ
Bảo vệ CSRFCần cookie SameSite + token CSRFKhông cần (token trong header)

Khi nào chọn Session Token

Session Token được ưa tiên khi: cần thu hồi phiên ngay lập tức (ngân hàng, bảng quản trị), ứng dụng chạy trên một hoặc nhiều máy chủ với Redis dùng chung, dữ liệu phiên lớn và không vừa với JWT, hoặc nhóm muốn giảm thiểu rủi ro rò rỉ dữ liệu qua giải mã token. Trong các kịch bản này, session token cung cấp khả năng chặn truy cập ngay lập tức khi có hoạt động đáng ngờ — chỉ cần xóa một bản ghi khỏi Redis, tất cả các phiên của người dùng sẽ trở nên không hợp lệ.

Theo Redis, 2025, việc sử dụng TTL ở cấp độ khóa phiên (lệnh EXPIRE) tự động dọn sạch các phiên đã hết hạn mà không tốn chi phí cho các tác vụ nền. Đối với các phiên có TTL 1 giờ và tải 10.000 người dùng đồng thời, Redis tiêu thụ khoảng 1 GB RAM với kích thước phiên 1 KB, giúp nó tiết kiệm chi phí cho hầu hết các ứng dụng.

Bảo mật Session Token

Bảo mật của session token dựa trên hai nguyên tắc: token phải không thể đoán trước và được bảo vệ trong quá trình truyền và lưu trữ. Các mối đe dọa chính là chặn token (man-in-the-middle, XSS), dự đoán token (tạo yếu) và cố định phiên (session fixation).

Bảo vệ khỏi đánh cắp token

Bảo vệ bao gồm: sử dụng HTTPS cho tất cả các yêu cầu có token, đặt TTL phiên ngắn (15–60 phút không hoạt động), gắn phiên với IP và user-agent (xác minh bổ sung ở mỗi yêu cầu), sử dụng các cờ Secure và HttpOnly cho cookie, và xoay vòng session token định kỳ sau các thao tác nhạy cảm (đổi mật khẩu, nâng cấp quyền). OWASP cũng khuyến nghị triển khai Quản lý Phiên với việc vô hiệu hóa phiên cũ khi tạo phiên mới sau khi đăng nhập — điều này ngăn chặn session fixation.

Theo OWASP ASVS, 2025, một phiên phải được gắn với ít nhất hai yếu tố: bản thân token (những gì client có) và IP/user-agent (những gì máy chủ biết). Nếu các yếu tố này không khớp, máy chủ phải kết thúc phiên và yêu cầu xác thực lại.

Ví dụ triển khai trong Kotlin

Dưới đây là ví dụ về triển khai session token phía máy chủ trong Kotlin sử dụng Spring Boot và Redis. Máy chủ tạo token an toàn mật mã hóa qua SecureRandom, lưu phiên trong Redis với TTL và xác thực nó ở mỗi yêu cầu. Mã nguồn minh họa ba thao tác chính: tạo phiên, xác thực và vô hiệu hóa.

kotlin
data class Session(
    val userId: Long,
    val role: String,
    val createdAt: Long,
    val lastAccess: Long
)

object SessionManager {
    private val redis = JedisPool("localhost", 6379)

    fun createSession(userId: Long, role: String): String {
        val token = generateSecureToken()
        val session = Session(userId, role, now(), now())
        redis.resource.use { conn ->
            conn.setex("session:$token", 3600, toJson(session))
        }
        return token
    }

    fun validateSession(token: String): Session? {
        redis.resource.use { conn ->
            val json = conn.get("session:$token") ?: return null
            return fromJson(json)
        }
    }

    fun invalidateSession(token: String) {
        redis.resource.use { it.del("session:$token") }
    }

    private fun generateSecureToken(): String {
        val bytes = ByteArray(32)
        SecureRandom().nextBytes(bytes)
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
    }
}

Triển khai này sử dụng JedisPool để kết nối an toàn luồng tới Redis. Phương thức createSession đặt TTL là 1 giờ (3600 giây) — sau khoảng thời gian này, Redis sẽ tự động xóa bản ghi. Phương thức validateSession trả về null cho các phiên không tồn tại hoặc đã hết hạn, cho phép máy chủ xử lý đúng yêu cầu với token không hợp lệ và trả về HTTP 401.

Câu hỏi thường gặp

Session token khác access token như thế nào?

Session token là định danh phiên phía máy chủ (stateful). Access token là thông tin đăng nhập để truy cập API (có thể là JWT hoặc opaque). Session token thường được sử dụng cho các phiên web, access token được sử dụng cho các yêu cầu API trong ứng dụng di động và SPA. Chúng có thể cùng tồn tại: session token cho web, access token cho API.

Làm thế nào để bảo vệ session token khỏi tấn công XSS?

Biện pháp bảo vệ chính là đặt cờ HttpOnly trên cookie chứa token phiên. Cờ này ngăn chặn truy cập cookie từ JavaScript, làm cho các cuộc tấn công XSS trở nên vô dụng để đánh cắp token. Ngoài ra, cờ SameSite=Strict ngăn chặn việc gửi cookie với các yêu cầu cross-site, bảo vệ khỏi CSRF.

Session token nên có thời gian sống bao lâu?

Hai thời gian chờ được khuyến nghị: thời gian chờ tuyệt đối (8–24 giờ — thời gian sống tối đa của phiên) và thời gian chờ tương đối (15–30 phút không hoạt động — sau đó phiên kết thúc). Đối với ứng dụng ngân hàng, thời gian chờ tuyệt đối được rút ngắn xuống 1–2 giờ; đối với client email, có thể lên tới 7 ngày.

Session fixation là gì?

Session fixation là một cuộc tấn công trong đó kẻ tấn công buộc người dùng sử dụng một định danh phiên đã biết. Bảo vệ: sau khi xác thực thành công, máy chủ phải tạo session token mới thay vì tiếp tục sử dụng token do client gửi đến. Token cũ phải được vô hiệu hóa bất kể nguồn gốc của nó.

Có thể sử dụng session token trong REST API không?

, session token phù hợp cho REST API nếu client gửi nó trong header Authorization (không phải cookie). Đối với ứng dụng di động, đây là thực hành phổ biến. Nhược điểm: khi mở rộng sang nhiều máy chủ, cần kho lưu trữ phiên dùng chung (Redis), làm tăng một điểm hỏng hóc duy nhất trong kiến trúc.

Tổng kết

  • Session Token — định danh stateful tham chiếu dữ liệu phiên phía máy chủ
  • Lợi thế — thu hồi ngay lập tức và kiểm soát hoàn toàn các phiên trên máy chủ
  • Lưu trữ — Redis, Memcached hoặc cơ sở dữ liệu với TTL để tự động dọn sạch
  • Bảo mật — tạo SecureRandom, HTTPS, cookie HttpOnly + SameSite
  • Session vs JWT — Session thu hồi dễ hơn, JWT mở rộng dễ hơn
  • Thời gian chờ — tuyệt đối (8–24 giờ) và tương đối (15–30 phút không hoạt động)
  • Session fixation — ngăn chặn bằng cách tạo token mới sau khi đăng nhập

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm