Quay lại
Access Token và Refresh Token là gì

Ở bài trước mình đã hướng dẫn các bạn cách xác thực REST API với JWT(JSON Web Token) thông qua một Access Token, và hôm nay chúng ta tiếp tục tìm hiểu về Refresh Token và sự khác biệt giữa chúng nhé và tại sao lại có thêm Refresh Token? Và Refresh Token dùng để làm gì? Nào let go !!!

Bạn biết đấy có rất nhiều tranh luận của mọi người trên mạng về vấn đề sử dụng Access Token và Refresh Token sao cho hợp lý. Có người thì bảo chỉ cần triển khai Access Token thôi là đủ, có người thì bảo cần thêm cả Refresh Token nữa mới bảo mật. Ngoài ra cũng có những câu hỏi vậy nếu có cả Access Token và Refresh Token thì tôi nên lưu ở đâu trong trình duyệt để đảm bảo độ an toàn tuyệt đối?

Vậy ngày hôm nay, tôi cùng các bạn hãy mổ xẻ lần lượt từng vấn đề để xem thực hư nó là như thế nào nhé!

Access Token là gì ?

Đầu tiên cho những ai chưa biết, Access Token là một đoạn string (thường là jwt) được dùng để đại diện cho người dùng thao tác vào hệ thống. Ví dụ như khi bạn đăng nhập vào hệ thống sẽ trả về cho bạn một Access Token , bạn lưu lại mã Access Token đó cho mỗi lần gọi API sau đó.

Nếu như các trang web được xây dựng theo phong cách server render thì ngoài cách triển khai Access Token và Refresh Token chúng ta còn có thể định phiên người dùng bằng session – cookie. Nhưng xu thế ngày nay đang hướng đến những trang web client render như React, Angular, Vue… thì việc triển khai Access Token và Refresh Token rất là phổ biến.

Refresh Token là gì?

Refresh Token là đoạn mã được dùng để yêu cầu cấp một mã Access Token mới.

Vấn đề ủy quyền là như thế nào?

Đầu tiên hãy làm rõ việc ủy quyền là gì? Thông thường việc xây dựng một website thì tính năng đăng ký/đăng nhập khá phổ biến. Đăng nhập thì bạn sẽ phải nhập một tài khoản + mật khẩu để xác nhận danh tính. Hệ thống xác nhận thông tin bạn nhập là chính xác thì sẽ trả về cho bạn một đoạn mã Access Token để đại diện cho bạn với một số quyền hạn nhất định trong hệ thống đó.

Hay trong Oauth, vấn đề ủy quyền thì nằm ở chỗ khi bạn bấm vào nút đăng ký/đăng nhập bằng tài khoản Google, Facebook… Hệ thống sẽ chuyển bạn qua một màn hình mà ở đó bạn sẽ phải đồng ý với việc cho phép cho hệ thống kia lấy một số thông tin như email, tên, ngày tháng năm sinh… của bạn. Khi đó thì Google hay Facebook cũng trả về một mã Access Token mà dựa vào đó, hệ thống kia có thể lấy được những thông tin của bạn phục vụ cho mục đính xác nhận danh tính.

Tóm lại, ủy quyền là việc xác nhận danh tính để lấy được một đoạn mã Access Token mà dựa vào mã Access Token đó có thể thay mặt người dùng để sử dụng được hệ thống.

Do đó, đôi khi việc có mã Access Token gần như là có luôn tài khoản của bạn trong một hệ thống nào đó. Việc bị lộ mã Access Token là rất nguy hiểm bởi vì kẻ tấn công có thể mạo danh bạn thao tác với hệ thống mà bạn hoàn toàn không hay biết. Chính vì lý do đó mã Access Token cần được lưu trữ một cách nghiêm ngặt nhất có thể, hoặc nếu không thì hãy giảm thời gian hiệu lực của mã Access Token lại, ví dụ như mã Access Token chỉ có hiệu lực trong thời gian 5 phút, hết 5 phút sẽ yêu cầu người dùng đăng nhập lại!? Nếu bạn chọn cách đó thì quả là một trải nghiệm tội tệ cho người dùng.

Mối quan hệ của Access Token và JWT

Một điều cần lưu ý là mã Access Token thường là mã JWT (json web token). Nó là một tiêu chuẩn để truyền thông tin an toàn giữa các bên với dữ liệu là một đối tượng JSON. Thông tin này có tính tin cậy cao bởi vì nó đã được kí bằng mã bí mật bằng các sử dụng các thuật toán như HMAC, RSA hoặc ECDSA.

Một đối tượng JWT gồm có 3 phần là header, payload và signature. Trong đó header giữ các thông tin cơ bản về chuỗi JWT như thuật toán dùng để kí, hạn sử dụng… Payload là dữ liệu cần truyền tải là đối tượng JSON đã được base64 encode. Cuối cùng là signature là phần mã hóa của cả hai header và payload kết hợp với mã bí mật cùng thuật toán mã hóa đã được chỉ định ở header.

Để tìm hiểu kĩ hơn về JWT, các bạn có thể đọc thêm ở Introduction to JSON Web Tokens .

Vì những thông tin cần thiết để truyền tải được nằm trong payload thế nên dựa vào payload hệ thống có thể xác định được danh tính của người dùng thông qua nó.

Ví dụ payload của mình có nội dung như sau:

{
  "id" : 1,
  "username": "hoaitx"
}

Thì khi lên hệ thống sẽ đọc được id của tôi và xác định được tôi là ai.

Có một lưu ý cực kì quan trọng đó là thông tin trong payload chỉ được mã hóa bằng base64, điều đó có nghĩa từ mã JWT tôi có thể trích xuất được những thông tin có trong payload vì thế bạn cần thận trọng trong việc đưa thông tin vào payload trước khi kí chúng. Chắc chắn rằng những thông tin nhạy cảm như password, hay các thông tin cá nhân không cần thiết thì không nên đưa vào.

Khi mã JWT được gửi lên máy chủ có thể dễ dàng xác định được phần chữ kí trong đó có hợp lệ không. Bởi bất kì một thông tin nào trong payload được sửa đổi để gửi lên sẽ kéo theo chữ kí sẽ bị thay đổi theo. Chưa kể đến kẻ tấn công sẽ không bao giờ biết được mã bí mật dùng để kí lại nội dung bị thay đổi đó.

Có nên dùng Refresh Token không?

Tôi sẽ không khuyến khích mọi người nên triển khai Refresh Token hay như thế nào. Vì tôi biết có nhiều hệ thống không cần triển khai đến Refresh Token mà vẫn hoạt động tốt. Thay vào đó tôi sẽ đưa ra một vài điểm cần chú ý khi sử dụng Access Token và Refresh Token .

Có một vài lý do để Access Token chỉ nên tồn tại trong thời gian ngắn như:

  • Access Token là một đoạn mã ủy quyền đã được kí bởi máy chủ ủy quyền, máy chủ tài nguyên chỉ cần nhận Access Token và xác nhận thế nên thời gian càng ngắn thì nguy cơ Access Token khi bị lộ càng ít rủi ro.
  • Nếu thời gian hợp lệ của Access Token quá dài, khi bị lộ Access Token thì rủi ro cao hơn vì t kẻ gian có nhiều thời gian hơn để khai thác, đồng thời có thể bạn ko biết rằng Access Token đã bị lộ.
  • Hãy tưởng tượng nếu bạn cho phép người dùng tạo quá nhiều mã Access Token , lúc đó nếu muốn vô hiệu hóa những mã Access Token còn lại thì bạn phải đánh dấu nó trong cơ sở dữ liệu. Hay nói cách khác là bạn cần phải lưu lại những mã Access Token đã được tạo ra.

Có một vài lý do để Refresh Token được sử dụng như:

  • Rút ngắn thời gian tồn tại của Access Token , khi Access Token bị hết hạn thì sử dụng Refresh Token để lấy mã Access Token mới.
  • Bạn cần phân biệt được máy chủ ủy quyền và máy chủ tài nguyên. Máy chủ ủy quyền có nhiệm vụ cung cấp mã Refresh Token và kí mã Access Token để đại diện cho người dùng. Máy chủ tài nguyên nhận mã đã kí từ máy chủ ủy quyền để có quyền như người dùng đang thao tác với dữ liệu của họ trên hệ thống như thông tin tài khoản, dữ liệu… Máy chủ ủy quyền và máy chủ tài nguyên có thể là một. Refresh Token thường được lưu trữ ở máy chủ ủy quyền phục vụ cho mục đích cấp mã Access Token mới. Còn mã Access Token được dùng ở máy chủ tài nguyên, dùng để định danh một người dùng.
  • Bạn không cần phải lưu lại nhiều Access Token , nếu muốn chấm dứt phiên chỉ đơn giản là vô hiệu hóa mã Refresh Token trên máy chủ ủy quyền.

Sau khi hiểu được những lý do trên thì việc sinh ra Refresh Token giúp giải quyết được một vài hạn chế khi chỉ sử dụng mỗi Access Token . Nhưng như vậy nếu mã Access Token hoặc Refresh Token bị lộ thì rủi ro sẽ rất cao sao? Và các lưu trữ chúng như thế nào thì mình xin viết tiếp ở phần sau.

Ví dụ dễ hiểu

Bây giờ đi vào vấn đề chính nhằm để giải thích Refresh Token la gi? và Refresh Token hoạt động như thế nào? Các bạn hãy tập trung vào ví dụ sau:

- Chủ nhà trọ chính là Authorization Server 

- Thằng thuê trọ chính là Client 

- Nhà trọ chính là Resource Owner 

- Khu nhà trọ chính là Resource Server

 Chìa khoá mở nhà trọ là Access Token 

Thẻ đi ra vào khi nhà trọ là Refresh Token 

Ok như vậy chúng ta đã định nghĩa được các chủ thể liên quan đến bài viết này, giờ chúng ta sẽ đi vào mô hình đi thuê nhà trọ.

Đó là một mô hình khi đi thuê nhà trọ giờ ra đi xem xét từng bước cụ thể để có cái nhìn toàn diện. 

(A) Thằng thuê trọ đi tìm thông tin và may mắn tìm thấy một nới qúa ngon và đến nhà thằng chủ trọ xin được thuê trọ. 

(B) Thằng chủ trọ xem xét mọi giấy tờ rồi pháp lý nếu cảm thấy thằng thuê trọ ngon thì xác nhận cho thuê. Nếu không thco thuê thì step A lặp lại :D, ngược lại nếu cho thuê thì thằng chủ trọ (Authorization Server) phải đưa cho thằng thuê nhà (Client) hai thứ đó là Chìa khoá (Access Token) và thẻ (Refresh Token) ra vào khu nhà trọ. 

(C) Thằng thuê trọ (Client) cầm Chìa khoá (Access Token) và thẻ (Refresh Token) đó cất giấu đâu tuỳ nó miễn là đừng để mất or bị trộm. Bỏi vì nếu bị trộm chìa khoá thì xem như mất đồ rắng chịu. Lỗi không phải của chủ nhà trọ nữa rồi. Và nó dùng Chìa khoá (Access Token) để vào nhà và sử dụng. Còn thẻ (Refresh Token) nói sau? vì nó rất đặc biệt 

(D) Nó dùng chìa khoá (Access Token) để mở nhà trọ nếu, nhà trọ nó xác thực được chìa khoá đó thì mở của xông vào. Nếu fail gặp thằng chủ nhà trọ hỏi chuyện? 

(E) Cứ như vậy đi học đi làm, (C) và (D) liên tục lặp lại cho đến khi chìa khoá bị hư (Access Token hết hạn). Nếu client làm được chìa khoá thì bỏ qua bước (G) nghĩa là nó có thể tự đi đánh chìa mới :D. 

(G) Client gửi một request lên Authorization Server để lấy một (Access Token) mới tuỳ theo những chính sách cụ thể. 

(H) Và cuối cùng của mô hình này là Authorization Server sẽ kiểm tra nếu hợp lệ thì sẽ cấp cho client một chìa khoá mới và có thể mà một (Refresh Token) mới. 

Đó là một mô hình hoàn chỉnh về việc xác thực việc thuê nhà trọ giữa các đối tượng cũng như các step trên. Nói tóm lại mô hình trên là như thế này. 

Client đi thuê nhà trọ thì phải tìm thông tin chính xác rồi gặp chủ nhà trọ để thuê trọ. CLient gửi CMND hay giấy tờ gì đó cho chủ nhà (gọi là pass, userID) nếu chủ nhà thấy tin tưởng và ok thì Chủ nhà trọ sẽ cấp cho client hai thứ đó là chia khoá và thẻ ra vào khu nhà trọ tương đương là Access Token và Refresh Token. Vì sao lại cả hai thì chút nữa giải thích tiếp.

Chìa khoá thì mở của nhà trọ đi vào và sử dụng tài sản cũng giống như dùng Access Token để lầy tài nguyên tại Resource Server. Và chú ý vì là chìa khoá nên có thể hư bất cứ lúc nào (đó là hết hạn của một Access Token). Còn Thẻ (Refresh Token) có nhiệm vụ sẽ lấy lại chìa khoá mới từ chủ nhà khi hư or mất. Khi đửa thẻ cho chủ nhà thì phải xác nhận lại CMND đại loại như thế. Đó chính là sự khác biệt. 

Vậy ở đây làm rõ những câu hỏi sau: 

#Tại sao phải là hai token mà không phải là một token?

Chỉ cần Access Token được giới hạn dài hơn là được? Cũng có những ý kiến như vậy nhưng ở đây việc Access Token ngắn hạn là điều nên làm như firebase chẳng hạn, google chỉ cho 1 giờ thôi là hết hạn. Cũng giống như các tài khoản ngân hàng, phiên làm việc rất ngắn hạn đảm bảo cho việc không bị tấn công qua token, token của client rất dễ bị lộ đa số storage như cookies... Cho nên cũng dễ hiểu vì sao Access Token ngắn hạn.

#Xác thực Access Token và Refresh Token khác biệt gì?

Đây là vấn đề cốt lõi của việc xác thực. Bạn xem hình ảnh trên có thể thấy việc xác thực một accest token chỉ làm việc tại Resource Server. Nhưng khi xác thực một Refresh Token thì nó lại làm việc trên Authorization Server. Vì Authorization Server không những bắt buộc có một Refresh Token mà còn gửi cả password và username lên nữa mới có thể sinh ra một token mới. Đó là một sự khác biệt lớn. 

#Vậy có thể nói Refresh Token tồn tại mãi mãi không?

Cũng có thể việc đó xảy ra nếu như nó không được đưa vào blacklist của system. Bởi vì những có chế xác thực luôn có những phương án thu hồi lại những token bị ngi nghờ trong quá trình sử dụng đó là blacklist. 

Còn gì nữa không nhỉ? Nếu các bạn có câu hỏi nào xin đặt vấn đề chúng ta sẽ cùng thảo luận, vì đè tài này khá hay. 

Bài viết chỉ mang tính cá nhân cho nên nếu có góp ý xin comment bên dưới nhé !. 

Bài viết đc tham khảo từ :

- https://2coffee.dev

Bình luận (0)

Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough
Michael Gough

Bài viết liên quan

Learning English Everyday