<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Session on Huy Vũ</title><link>https://vuvtdhh.pages.dev/tags/session/</link><description>Recent content in Session on Huy Vũ</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><copyright>Huy Vũ</copyright><lastBuildDate>Sun, 03 May 2026 10:00:00 +0700</lastBuildDate><atom:link href="https://vuvtdhh.pages.dev/tags/session/index.xml" rel="self" type="application/rss+xml"/><item><title>Từ Monolith đến Microservices: Tại sao Phantom Token là lựa chọn tối ưu cho Authentication?</title><link>https://vuvtdhh.pages.dev/p/t%E1%BB%AB-monolith-%C4%91%E1%BA%BFn-microservices-t%E1%BA%A1i-sao-phantom-token-l%C3%A0-l%E1%BB%B1a-ch%E1%BB%8Dn-t%E1%BB%91i-%C6%B0u-cho-authentication/</link><pubDate>Sun, 03 May 2026 10:00:00 +0700</pubDate><guid>https://vuvtdhh.pages.dev/p/t%E1%BB%AB-monolith-%C4%91%E1%BA%BFn-microservices-t%E1%BA%A1i-sao-phantom-token-l%C3%A0-l%E1%BB%B1a-ch%E1%BB%8Dn-t%E1%BB%91i-%C6%B0u-cho-authentication/</guid><description>&lt;h2 id="3-mẫu-kiến-trúc-xác-thực-kinh-điển-trong-ứng-dụng-web"&gt;3 mẫu kiến trúc xác thực kinh điển trong ứng dụng Web
&lt;/h2&gt;&lt;p&gt;Hầu hết các hệ thống xác thực (Authentication) cho ứng dụng Web hiện nay đều xoay quanh 3 mẫu thiết kế nền tảng:&lt;/p&gt;
&lt;h3 id="stateful-session-pattern"&gt;Stateful Session Pattern
&lt;/h3&gt;&lt;p&gt;Đây là mô hình kinh điển nhất, gắn liền với các framework Web truyền thống như ASP.NET MVC hay PHP.&lt;/p&gt;
&lt;p&gt;Sau khi đăng nhập, server tạo một phiên làm việc (Session) và lưu vào bộ nhớ (RAM/Redis). Client chỉ nhận về một Session ID vô nghĩa, được lưu trong &lt;strong&gt;HttpOnly Cookie&lt;/strong&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ưu điểm:&lt;/strong&gt; Cực kỳ bảo mật — dữ liệu thực (Claims) không bao giờ rời khỏi server. Muốn thu hồi phiên làm việc? Chỉ cần xóa Session ở server là xong.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhược điểm:&lt;/strong&gt; Triển khai Session trong Microservices đòi hỏi Shared Cache hoặc cấu hình Sticky Sessions trên Load Balancer, đồng thời gây rắc rối khi xử lý các chính sách SameSite Cookie trên đa domain. Điều này làm mất đi tính Stateless và sự độc lập của mỗi service.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;
sequenceDiagram
participant B as Browser
participant S as Server
participant C as Cache/Database
B-&amp;gt;&amp;gt;S: 1. Gửi credentials (user/pass)
S-&amp;gt;&amp;gt;S: 2. Xác thực thông tin
S-&amp;gt;&amp;gt;C: 3. Tạo Session, lưu Session ID
S--&amp;gt;&amp;gt;B: 4. Trả về HttpOnly Cookie (Session ID)
B-&amp;gt;&amp;gt;S: 5. Gửi request + Cookie (Session ID)
S-&amp;gt;&amp;gt;C: 6. Kiểm tra Session ID
S--&amp;gt;&amp;gt;B: 7. Trả về Resource
&lt;/pre&gt;
&lt;h3 id="token-by-value-pattern-stateless-jwt"&gt;Token-by-Value Pattern (Stateless JWT)
&lt;/h3&gt;&lt;p&gt;Mô hình này bùng nổ cùng với sự phát triển của Single Page Application và Mobile App.&lt;/p&gt;
&lt;p&gt;Toàn bộ thông tin người dùng được đóng gói vào một &lt;strong&gt;JWT&lt;/strong&gt; và ký số. Server không lưu trạng thái (Stateless) — client tự giữ token và gửi kèm trong header &lt;code&gt;Authorization&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ưu điểm:&lt;/strong&gt; Scale rất tốt vì server không cần truy vấn DB/cache để xác thực. Phù hợp với kiến trúc Microservices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhược điểm:&lt;/strong&gt; Hacker có thể giải mã Base64 để đọc nội dung bên trong (rò rỉ PII). Một khi JWT đã được phát ra, gần như không có cách nào thu hồi trước khi hết hạn. Việc để lộ cấu trúc Claims hoặc ID người dùng trong JWT (dù đã mã hóa Base64) là một điểm trừ lớn khi Audit.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;
sequenceDiagram
participant B as Browser
participant S as Server
participant R as Resource API
B-&amp;gt;&amp;gt;S: 1. Gửi credentials (user/pass)
S-&amp;gt;&amp;gt;S: 2. Xác thực thông tin
S--&amp;gt;&amp;gt;B: 3. Tạo JWT (chứa Claims, ký số), trả về Client
B-&amp;gt;&amp;gt;B: 4. Lưu JWT (LocalStorage/Memory)
B-&amp;gt;&amp;gt;R: 5. Gửi request + Authorization: Bearer JWT
R-&amp;gt;&amp;gt;R: 6. Giải mã, kiểm tra chữ ký JWT (Stateless)
R--&amp;gt;&amp;gt;B: 7. Trả về Resource
&lt;/pre&gt;
&lt;h3 id="token-by-reference-pattern-opaque-token"&gt;Token-by-Reference Pattern (Opaque Token)
&lt;/h3&gt;&lt;p&gt;Thường dùng trong các hệ thống yêu cầu bảo mật cao hoặc các Identity Server chuyên dụng.&lt;/p&gt;
&lt;p&gt;Server trả về một chuỗi ngẫu nhiên vô nghĩa (Opaque Token), còn thông tin thực sự được lưu tập trung tại Identity Server.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ưu điểm:&lt;/strong&gt; Client không chứa bất kỳ dữ liệu nhạy cảm nào.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhược điểm:&lt;/strong&gt; Mỗi lần cần xác thực, Resource API phải gọi ngược về Identity Server (Introspection) để giải mã token — tạo ra &amp;ldquo;điểm nghẽn&amp;rdquo; khi traffic lớn.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="mermaid"&gt;
sequenceDiagram
participant B as Browser
participant S as Server
participant I as Identity Server
participant R as Resource API
B-&amp;gt;&amp;gt;S: 1. Gửi credentials (user/pass)
S-&amp;gt;&amp;gt;I: 2. Xác thực, tạo Opaque Token, lưu vào cache
I--&amp;gt;&amp;gt;B: 3. Trả về Opaque Token (chuỗi ngẫu nhiên)
B-&amp;gt;&amp;gt;R: 4. Gửi request + Opaque Token
R-&amp;gt;&amp;gt;I: 5. Gọi Introspection để giải mã token
I--&amp;gt;&amp;gt;R: 6. Trả về Claims thông tin người dùng
R--&amp;gt;&amp;gt;B: 7. Trả về Resource
&lt;/pre&gt;
&lt;hr&gt;
&lt;h2 id="giải-pháp-tối-ưu-phantom-token-pattern"&gt;Giải pháp tối ưu: Phantom Token Pattern
&lt;/h2&gt;&lt;p&gt;Nhận ra điểm yếu của cả hai hướng trên, &lt;strong&gt;Phantom Token Pattern&lt;/strong&gt; ra đời như một sự kết hợp thông minh: dùng &lt;strong&gt;Opaque Token&lt;/strong&gt; làm lớp bảo mật bên ngoài, và &lt;strong&gt;JWT&lt;/strong&gt; làm động cơ hiệu năng bên trong.&lt;/p&gt;
&lt;h3 id="cơ-chế-vận-hành"&gt;Cơ chế vận hành
&lt;/h3&gt;&lt;p&gt;Mẫu thiết kế này chia hệ thống thành hai vùng rõ rệt: &lt;strong&gt;Public Zone&lt;/strong&gt; (không tin cậy) và &lt;strong&gt;Private Zone&lt;/strong&gt; (tin cậy).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Cấp phát:&lt;/strong&gt; Khi đăng nhập, Identity Server tạo JWT đầy đủ claims nhưng &lt;em&gt;không gửi đi&lt;/em&gt;. Nó lưu JWT vào cache và chỉ trả về cho Client một &lt;strong&gt;Opaque Token&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gửi request:&lt;/strong&gt; Client gửi request kèm Opaque Token đến &lt;strong&gt;API Gateway&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hoán đổi token:&lt;/strong&gt; Tại API Gateway (nằm ở biên mạng), Gateway nhận Opaque Token và gọi sang Identity Server để đổi lấy &lt;strong&gt;JWT&lt;/strong&gt; tương ứng.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Xử lý nội bộ:&lt;/strong&gt; Gateway thay thế Opaque Token bằng JWT trong header rồi forward vào các Microservices bên trong.&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class="mermaid"&gt;
sequenceDiagram
box rgb(255, 245, 230) Public Zone
participant B as Browser
participant N as Internet
end
box rgb(230, 245, 255) Private Zone
participant G as API Gateway
participant I as Identity Server
participant M as Microservices
end
B-&amp;gt;&amp;gt;N: 1. Gửi credentials (user/pass)
N-&amp;gt;&amp;gt;G: 2. Chuyển tiếp tới Gateway
G-&amp;gt;&amp;gt;I: 3. Điều phối xác thực
I-&amp;gt;&amp;gt;I: 4. Xác thực, tạo JWT, lưu vào cache
I--&amp;gt;&amp;gt;G: 5. Trả về Opaque Token
G--&amp;gt;&amp;gt;B: 6. Trả về Opaque Token cho Client
B-&amp;gt;&amp;gt;G: 7. Gửi request + Opaque Token (qua Internet)
G-&amp;gt;&amp;gt;I: 8. Exchange: gửi Opaque Token
I--&amp;gt;&amp;gt;G: 9. Trả về JWT tương ứng
G-&amp;gt;&amp;gt;G: 10. Thay Opaque Token bằng JWT trong header
G-&amp;gt;&amp;gt;M: 11. Forward request + JWT
M-&amp;gt;&amp;gt;M: 12. Xử lý Stateless (như Token-by-Value)
M--&amp;gt;&amp;gt;B: 13. Trả về Resource
&lt;/pre&gt;
&lt;h3 id="tại-sao-gọi-là-phantom"&gt;Tại sao gọi là &amp;ldquo;Phantom&amp;rdquo;?
&lt;/h3&gt;&lt;p&gt;Vì đối với Client, JWT hoàn toàn không tồn tại. Nó như một &amp;ldquo;bóng ma&amp;rdquo; — chỉ xuất hiện và lưu hành bên trong vùng mạng nội bộ của hệ thống.&lt;/p&gt;
&lt;h3 id="ưu-điểm-vượt-trội"&gt;Ưu điểm vượt trội
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bảo mật đa lớp (Defense in Depth &amp;amp; PII Protection):&lt;/strong&gt; Thông tin nhạy cảm (User ID, Role, Email&amp;hellip;) được đóng gói trong JWT và chỉ lưu hành trong mạng nội bộ. Client chỉ nhận Opaque Token vô nghĩa, triệt tiêu hoàn toàn nguy cơ rò rỉ dữ liệu cá nhân (PII) ra Internet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thu hồi quyền truy cập tức thì (Immediate Revocation):&lt;/strong&gt; Khác với JWT truyền thống khó thu hồi trước khi hết hạn, Opaque Token có thể bị vô hiệu hóa ngay lập tức tại API Gateway hoặc Identity Server, giúp kiểm soát phiên làm việc của người dùng chặt chẽ hơn.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tối ưu hiệu năng Microservices:&lt;/strong&gt; Các service phía sau Gateway nhận được JWT đã được &amp;ldquo;giải mã sẵn&amp;rdquo;, cho phép xử lý Stateless hoàn toàn mà không cần gọi ngược về Identity Server (Introspection). Ngoài ra, request từ Client qua mạng cũng nhẹ hơn nhờ payload của Opaque Token rất gọn.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tách biệt trách nhiệm (Separation of Concerns)&lt;/strong&gt;: Identity Server lo việc phát hành/định danh. API Gateway lo việc chuyển đổi (Introspection). Microservices chỉ quan tâm đến Business Logic với một JWT sạch.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="khi-nào-nên-dùng"&gt;Khi nào nên dùng?
&lt;/h3&gt;&lt;p&gt;Phantom Token Pattern đặc biệt phù hợp khi bạn xây dựng hệ thống &lt;strong&gt;Microservices&lt;/strong&gt; hiện đại, có yêu cầu bảo mật cao, và muốn tách biệt rõ ràng trách nhiệm giữa Security và Business Logic.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lời kết:&lt;/strong&gt; Phantom Token không chỉ là một kỹ thuật xác thực — nó là tư duy thiết kế bảo mật theo chiều sâu. Vừa đạt được sự an toàn của Opaque Token, vừa giữ được hiệu năng của JWT.&lt;/p&gt;
&lt;/blockquote&gt;</description></item></channel></rss>