thắc mắc Không cảm thấy refresh token thực sự giải quyết vấn đề

  • Người tạo chủ đề Người tạo chủ đề xuanduy1508
  • Ngày bắt đầu Ngày bắt đầu

xuanduy1508

Junior Member
Chào mọi người, em đây mới học về Jwt và em có một thắc mắc refresh token có thực sự giải quyết vấn đề không ạ.
Nếu như em hiểu thì:
user login => nhận access token (at) có thời hạn ngắn và refresh token (rt) có thời hạn dài => gửi request thì kèm cả hai at và rt vào header => nếu at còn thời hạn thì cho đụng vào resource, nếu không còn thời hạn thì cung cấp at và rt mới và lưu rt cũ vào blacklist.

Nếu em hiểu sai flow trên thì mong mọi người thông cảm, và đây là câu hỏi của em:
Refresh token được cho rằng có tác dụng như sau:
+ "Tại vì access token thời hạn ngắn, với refresh token thì người dùng không cần đăng nhập lại khi hết hạn access token. Thay vào đó, refresh token tự động lấy access token mới, duy trì trạng thái đăng nhập và cho phép sử dụng ứng dụng liên tục."=> Vậy thì sao không tăng thời gian hết hạn của access token luôn cho khoẻ ạ?
+"Access token có thời gian hiệu lực ngắn, do đó, việc lộ lọt cũng chỉ ảnh hưởng trong thời gian ngắn. Sau khi hết hạn, refresh token sẽ được sử dụng để lấy access token mới, giúp giảm thiểu thiệt hại do rò rỉ thông tin." => Rõ ràng là at và rt đều lưu chung trong cookie, đều được gửi lên cùng với request. Vậy thì nếu ăn cắp dc at thì cũng ăn cắp dc rt. Có rt thì xin at cái rụp thì em cũng không rõ là nó tăng bảo mật chỗ này như nào ạ.
+"Nếu hoạt động đáng ngờ được phát hiện trên tài khoản của người dùng, refresh token của họ có thể bị revoke để ngăn chặn kẻ tấn công sử dụng nó để truy cập tài khoản." => ủa thì at một mình nó cũng có thể revoke được mà, mắc gì cần refresh token chi ạ @@

Và một câu hỏi bonus về việc "nhận biết hành động đáng ngờ" em coi được ở vid này
:
(tóm tắt em lấy ở dưới cmt như sau:
1 Cả RT và AT đều cùng được cấp mới mỗi lần tạo mới AT, và lưu lại RT cũ. 2 Một khi RT cũ bị sử dụng lại (không cần phân biệt user hay hacker) thì hủy toàn bộ RT đang hoạt động. 3 User đăng nhập lại và lấy RT mới.
). Em chả thấy lý do gì mà thằng hacker phải xài rt cũ cả, lúc mà nó dùng rt để xin cặp at và rt mới thì nó cũng nhận được rt mới mà. Vậy thì mắc mớ gì nó xài rt cũ chi ạ @@.

Em mới học nên ngu mụi, mong được mọi người giải đáp
 
AT và RT ai lại gửi cùng lúc như bạn thế. RT chỉ dùng gửi lên server cấp quyền khi AT hết hạn thôi
 
Refresh token hoạt động như logged-in session, tương tự như user gửi cả username+password. Còn access token thì hoạt động như “remember me”, tức mỗi lần gửi access token lên thì server có thể validate user đang login hợp lệ mà (hầu như) không cần hit database, giảm db/backend load. Access token có thời hạn ngắn (thường là 1 ngày) để tránh access token bị leak (MITM/spoof) mà ko revoke được (again không cần hit database)
 
Phát ngôn câu trước đá câu sau

Ở trên thì hỏi "tại sao không tăng thời gian valid access token" lên

Ở dưới lại kêu "access token thời gian ngắn nên an toàn"

:confuse::confuse::doubt:

Mới học thì nên đọc tài liệu Oauth2.0, Oauth for browser-based app của RFC rồi hẳn hỏi chứ hỏi ngu ngơ thế này mời # sau giải đáp

P/s: cá là anh bạn này còn không biết phân biệt 4 role trong oauth2 nữa
 
Mới học thì nên đọc tài liệu Oauth2.0, Oauth for browser-based app của RFC rồi hẳn hỏi chứ hỏi ngu ngơ thế này mời # sau giải đáp

P/s: cá là anh bạn này còn không biết phân biệt 4 role trong oauth2 nữa
Người ta hỏi JWT ông lại kêu học OAuth, sao troll vậy :beat_brick:
 
bình thường chỉ gửi kèm access token, khi nào access token hết hạn mới gửi refresh token. Ko ai gửi kèm cả
 
Đây nhé, lợi ích của cái việc đẻ ra RT và AT đó là nếu được implement đầy đủ bên server thì sẽ detect được khi nào cái AT hoặc/và RT đã bị cướp bởi bên thứ 3.

Yêu cầu:
- Cần server phải có lưu trên DB map 1-1 giữa RT và cái AT gần nhất vừa được tạo ra từ nó

Trường hợp xảy ra: Hackers chiếm được cả RT và AT
  • Vì AT sẽ nhanh chóng expire nên hacker sẽ nhanh phải cần dùng đến RT để tiếp tục có access vào hệ thống qua những cái AT mới
  • Người dùng thật cũng như vậy, liên tục phải xin AT mới bằng RT
  • Lúc này 1 cái RT sẽ được dùng để sinh ra 2 cái AT với time window bị overlap. 1 cho hacker và 1 cho người dùng thật
  • Do server đã được implement cái map 1-1 giữa RT và cái AT gần nhất nó tạo ra nên khi hacker và người dùng sẽ dùng 2 cái ATs từ cùng một RT, và server sẽ từ chối access cho cái AT cũ hơn. Sẽ có khả năng cao người dùng sẽ bị không vào được hệ thống và sẽ cảm thấy nghi ngờ

Lúc này sẽ có 2 giải pháp:
  • Bên server invalidate cái RT mà đã được dùng để tạo ra 2 cái ATs trong cùng 1 time window. Vậy là hackers lại phải chiếm lại RT và AT, và người dùng phải login lại. Vậy là an toàn hơn rồi
  • Bên client app sau khi không access được thì sẽ báo users để users biết được có thằng đang dùng chung với mình cái RT để users xử lý tiếp. Như vậy cũng đã nhiều bảo mật hơn.

Viết hơi dài chút nhưng chắc cũng dễ hiểu. Có gì chú cứ hỏi lại nhé.
 
Đây nhé, lợi ích của cái việc đẻ ra RT và AT đó là nếu được implement đầy đủ bên server thì sẽ detect được khi nào cái AT hoặc/và RT đã bị cướp bởi bên thứ 3.

Yêu cầu:
- Cần server phải có lưu trên DB map 1-1 giữa RT và cái AT gần nhất vừa được tạo ra từ nó

Trường hợp xảy ra: Hackers chiếm được cả RT và AT
  • Vì AT sẽ nhanh chóng expire nên hacker sẽ nhanh phải cần dùng đến RT để tiếp tục có access vào hệ thống qua những cái AT mới
  • Người dùng thật cũng như vậy, liên tục phải xin AT mới bằng RT
  • Lúc này 1 cái RT sẽ được dùng để sinh ra 2 cái AT với time window bị overlap. 1 cho hacker và 1 cho người dùng thật
  • Do server đã được implement cái map 1-1 giữa RT và cái AT gần nhất nó tạo ra nên khi hacker và người dùng sẽ dùng 2 cái ATs từ cùng một RT, và server sẽ từ chối access cho cái AT cũ hơn. Sẽ có khả năng cao người dùng sẽ bị không vào được hệ thống và sẽ cảm thấy nghi ngờ

Lúc này sẽ có 2 giải pháp:
  • Bên server invalidate cái RT mà đã được dùng để tạo ra 2 cái ATs trong cùng 1 time window. Vậy là hackers lại phải chiếm lại RT và AT, và người dùng phải login lại. Vậy là an toàn hơn rồi
  • Bên client app sau khi không access được thì sẽ báo users để users biết được có thằng đang dùng chung với mình cái RT để users xử lý tiếp. Như vậy cũng đã nhiều bảo mật hơn.

Viết hơi dài chút nhưng chắc cũng dễ hiểu. Có gì chú cứ hỏi lại nhé.
Fen giải thích giúp mình đoạn implement 1-1 và server từ chối truy cập cho cái token cũ hơn được ko ? Giả dụ cả người dùng và hacker dùng RT get về 2 cái AT cùng lúc . Làm sao để server biết được cái nào cũ hơn cái nào ( chắc chắn là 2 cái AT đó đều pass qua auth rồi do chưa hết expire) . Chẳng lẽ mỗi lần request đều check trong db để check cái nào mới nhất
 
Fen giải thích giúp mình đoạn implement 1-1 và server từ chối truy cập cho cái token cũ hơn được ko ? Giả dụ cả người dùng và hacker dùng RT get về 2 cái AT cùng lúc . Làm sao để server biết được cái nào cũ hơn cái nào ( chắc chắn là 2 cái AT đó đều pass qua auth rồi do chưa hết expire) . Chẳng lẽ mỗi lần request đều check trong db để check cái nào mới nhất
Chính xác. Mỗi lần request đến hệ thống đều phải kiểm tra trên DB xem cái AT mới nhất được map 1-1 với cái RT được gửi kèm có trùng id với cái AT được gửi kèm không.
 
+ "Tại vì access token thời hạn ngắn, với refresh token thì người dùng không cần đăng nhập lại khi hết hạn access token. Thay vào đó, refresh token tự động lấy access token mới, duy trì trạng thái đăng nhập và cho phép sử dụng ứng dụng liên tục."=> Vậy thì sao không tăng thời gian hết hạn của access token luôn cho khoẻ ạ?
Tăng thời hạn của AT thì attacker khi chiếm đc AT sẽ có nhiều thời gian access vào resouces server hơn
Solution → giảm valid time của AT (eg. 1 hour) → khi AT expired, client app sẽ tự động gửi request đến Authorization Server để get new pair of AT và RT (cả RT cũng sẽ được cấp mới)

+"Access token có thời gian hiệu lực ngắn, do đó, việc lộ lọt cũng chỉ ảnh hưởng trong thời gian ngắn. Sau khi hết hạn, refresh token sẽ được sử dụng để lấy access token mới, giúp giảm thiểu thiệt hại do rò rỉ thông tin." => Rõ ràng là at và rt đều lưu chung trong cookie, đều được gửi lên cùng với request. Vậy thì nếu ăn cắp dc at thì cũng ăn cắp dc rt. Có rt thì xin at cái rụp thì em cũng không rõ là nó tăng bảo mật chỗ này như nào ạ.
Attacker hoàn toàn có thể chiếm đc RT.
Các Authorization Server thường implement một cơ chế gọi là Automatic Reuse Detection để detect việc RT được reuse.
VD một scenarios như này
  • Legit User (LU)RT1AT1
  • Malicious User (MU) đánh cắp được RT1 từ LU
  • LU sử dụng RT1 để get 1 cặp RTAT mới
  • Authorization Server trả về RT2AT2 cho LU
  • MU sau đó cũng sử dụng RT1 (đã bị đánh cắp từ trước) để get một cặp ATRT mới → RT reuse detected
Để implement được cơ chế này thì các Authorization Server thường lưu các token family, nghĩa là từ một RT ban đầu sẽ có link tới các RT đã được generate sau đó, có thể dùng linked list.
Khi MU cố gắng sử dụng RT1 (đã bị đánh cắp từ trước) để get một cặp ATRT mới → Authorization Server sẽ check được RT1 được sử dụng trước đó → invalidates toàn bộ tokens trong token family hiện tại → RT2AT2LU đang sử dụng cũng sẽ bị invalidated → LU sẽ phải thực hiện đăng nhập lại

+"Nếu hoạt động đáng ngờ được phát hiện trên tài khoản của người dùng, refresh token của họ có thể bị revoke để ngăn chặn kẻ tấn công sử dụng nó để truy cập tài khoản." => ủa thì at một mình nó cũng có thể revoke được mà, mắc gì cần refresh token chi ạ @@
AT chỉ là token để access vào Resources Server, còn RT sẽ tăng thêm bảo mật cho hệ thống (bằng các chế được mô tả ở trên). VD nếu dùng RT với service của Auth0 thì mình sẽ không phải tự implement cơ chế Automatic Reuse Detection vào Resource Server.
rt-and-at.png
 
Người ta hỏi JWT ông lại kêu học OAuth, sao troll vậy :beat_brick:
JWT chỉ là 1 dạng encode access token thôi

Thực tế là chỉ có Oauth2 authentication chứ làm đéo gì có cái gọi là JWT authentication. Coi thử đi có cái RFC nào quy định cho cái JWT authentication không?

Www Authorization header nó dùng cái Bearer scheme cũng của Oauth2. Còn cái bọn dùng JWT authentication chả qua cũng tự chế lại cái implicit flow từ oauth2 rồi dùng token như session cookie chứ có gì đâu
 
cho em hỏi bên frontend sẽ xử lý việc tự động gửi request này
như nào ạ
Về cơ bản thì khi client send request với AT đã expired thì Resource Server sẽ gửi về error (eg. 403 Unauthorized)
Ở phía client mình sẽ handle khi nhận error response này thì sẽ gửi 1 request khác (với param là RT) đến Authorization Server để get new AT và RT

Fen có thể tham khảo thêm
 
Về cơ bản thì khi client send request với AT đã expired thì Resource Server sẽ gửi về error (eg. 403 Unauthorized)
Ở phía client mình sẽ handle khi nhận error response này thì sẽ gửi 1 request khác (với param là RT) đến Authorization Server để get new AT và RT

Fen có thể tham khảo thêm
Nếu dùng JWT thì self-contained nên cần gì gửi tới resource server bác nhỉ.
Theo mình thì access token short-live sẽ được resource server check 1 cách độc lập, không đi kèm các cơ chế detect nặng như các bác nêu ở trên. Và khi bị leak thì attacker có rất ít thời gian để tấn công
Ngược lại mục đích của refresh token long-live là chỉ gửi khi renew access token nên khó bị leak. Mình đọc flow thấy khi renew thì phải gửi kèm cả client-id và client-secret tới authorization server nên dù bị leak vẫn không sao nhỉ. Mong các bác giải đáp
 
Nếu dùng JWT thì self-contained nên cần gì gửi tới resource server bác nhỉ.
Theo mình thì access token short-live sẽ được resource server check 1 cách độc lập, không đi kèm các cơ chế detect nặng như các bác nêu ở trên. Và khi bị leak thì attacker có rất ít thời gian để tấn công
Ngược lại mục đích của refresh token long-live là chỉ gửi khi renew access token nên khó bị leak. Mình đọc flow thấy khi renew thì phải gửi kèm cả client-id và client-secret tới authorization server nên dù bị leak vẫn không sao nhỉ. Mong các bác giải đáp
Gọi RT là long-live ko đúng lắm, vì về cơ bản RT cũng sẽ được renew khi client gửi request để renew AT. Chẳng qua đứng ở phía UX, user sẽ ko phải re-login manually (vì client app đã chủ động renew AT và RT khi AT expired) nên mình sẽ cảm tưởng RT là long-live

Và RT cũng hoàn toàn có thể bị leak dễ dàng (vd nếu lưu ở localStorage trên browser), nên theo mình việc RT khó bị leak cũng ko đúng lắm. Quan trọng là ở phía Authorization Server đã có những cơ chế (eg. RT Automatic Reuse Detection) để nếu RT có bị leak thì cũng vấn đảm bảo được security.

Về self-contained JWT, thì theo kinh nghiệm của mình, JWT thường được dùng cho authorization. Mình có thể design JWT chứa các aud scopes claims tương ứng với user cụ thể. Ở Resource Server, khi nhận được AT (JWT format), Resource Server sẽ decode token và biết được user đó có permission đối với resources nào.
 
Đây nhé, lợi ích của cái việc đẻ ra RT và AT đó là nếu được implement đầy đủ bên server thì sẽ detect được khi nào cái AT hoặc/và RT đã bị cướp bởi bên thứ 3.

Yêu cầu:
- Cần server phải có lưu trên DB map 1-1 giữa RT và cái AT gần nhất vừa được tạo ra từ nó

Trường hợp xảy ra: Hackers chiếm được cả RT và AT
  • Vì AT sẽ nhanh chóng expire nên hacker sẽ nhanh phải cần dùng đến RT để tiếp tục có access vào hệ thống qua những cái AT mới
  • Người dùng thật cũng như vậy, liên tục phải xin AT mới bằng RT
  • Lúc này 1 cái RT sẽ được dùng để sinh ra 2 cái AT với time window bị overlap. 1 cho hacker và 1 cho người dùng thật
  • Do server đã được implement cái map 1-1 giữa RT và cái AT gần nhất nó tạo ra nên khi hacker và người dùng sẽ dùng 2 cái ATs từ cùng một RT, và server sẽ từ chối access cho cái AT cũ hơn. Sẽ có khả năng cao người dùng sẽ bị không vào được hệ thống và sẽ cảm thấy nghi ngờ

Lúc này sẽ có 2 giải pháp:
  • Bên server invalidate cái RT mà đã được dùng để tạo ra 2 cái ATs trong cùng 1 time window. Vậy là hackers lại phải chiếm lại RT và AT, và người dùng phải login lại. Vậy là an toàn hơn rồi
  • Bên client app sau khi không access được thì sẽ báo users để users biết được có thằng đang dùng chung với mình cái RT để users xử lý tiếp. Như vậy cũng đã nhiều bảo mật hơn.

Viết hơi dài chút nhưng chắc cũng dễ hiểu. Có gì chú cứ hỏi lại nhé.
Tăng thời hạn của AT thì attacker khi chiếm đc AT sẽ có nhiều thời gian access vào resouces server hơn
Solution → giảm valid time của AT (eg. 1 hour) → khi AT expired, client app sẽ tự động gửi request đến Authorization Server để get new pair of AT và RT (cả RT cũng sẽ được cấp mới)


Attacker hoàn toàn có thể chiếm đc RT.
Các Authorization Server thường implement một cơ chế gọi là Automatic Reuse Detection để detect việc RT được reuse.
VD một scenarios như này
  • Legit User (LU)RT1AT1
  • Malicious User (MU) đánh cắp được RT1 từ LU
  • LU sử dụng RT1 để get 1 cặp RTAT mới
  • Authorization Server trả về RT2AT2 cho LU
  • MU sau đó cũng sử dụng RT1 (đã bị đánh cắp từ trước) để get một cặp ATRT mới → RT reuse detected
Để implement được cơ chế này thì các Authorization Server thường lưu các token family, nghĩa là từ một RT ban đầu sẽ có link tới các RT đã được generate sau đó, có thể dùng linked list.
Khi MU cố gắng sử dụng RT1 (đã bị đánh cắp từ trước) để get một cặp ATRT mới → Authorization Server sẽ check được RT1 được sử dụng trước đó → invalidates toàn bộ tokens trong token family hiện tại → RT2AT2LU đang sử dụng cũng sẽ bị invalidated → LU sẽ phải thực hiện đăng nhập lại


AT chỉ là token để access vào Resources Server, còn RT sẽ tăng thêm bảo mật cho hệ thống (bằng các chế được mô tả ở trên). VD nếu dùng RT với service của Auth0 thì mình sẽ không phải tự implement cơ chế Automatic Reuse Detection vào Resource Server.
Xem tệp đính kèm 2591820
Em cảm ơn hai bác vì câu trả lời chi tiết ạ. Nhưng em vẫn cảm thấy rằng một JWT access token thôi cũng đủ sức làm chuyện này rồi ạ.

VD một scenarios như này
  • Legit User (LU) sau khi login có 1 access token (AT1)
  • Malicious User (MU) đánh cắp được AT1 từ LU
  • LU gửi request gì đó như post một Product mới lên server cùng với AT1
    Nếu AT1 valid, cho LU post một Product mới và cung cấp cho LU một AT mới là AT2
  • MU sau đó cũng sử dụng AT1 (đã bị đánh cắp từ trước) để gửi refresh lên server → AT reuse detected

    Xong rồi revoke AT2 bắt LU login lại và cảnh báo LU

    Đó, theo em thấy thì một mình một token thôi cũng đủ để xử lý vấn đề rồi ạ. Cơ sự gì xin ra 2 thằng riêng biệt AT với RT chi ạ
 
Sửa lần cuối:
Em cảm ơn hai bác vì câu trả lời chi tiết ạ. Nhưng em vẫn cảm thấy rằng một JWT access token thôi cũng đủ sức làm chuyện này rồi ạ.

VD một scenarios như này
  • Legit User (LU) sau khi login có 1 access token (AT1)
  • Malicious User (MU) đánh cắp được AT1 từ LU
  • LU gửi request gì đó như post một Product mới lên server cùng với AT1
    Nếu AT1 valid, cho LU post một Product mới và cung cấp cho LU một AT mới là AT2
  • MU sau đó cũng sử dụng AT1 (đã bị đánh cắp từ trước) để gửi refresh lên server → AT reuse detected

    Xong rồi revoke AT2 bắt LU login lại và cảnh báo LU

    Đó, theo em thấy thì một mình một token thôi cũng đủ để xử lý vấn đề rồi ạ. Cơ sự gì xin ra 2 thằng riêng biệt AT với RT chi ạ

Bên mình thiết kế sử dụng AT và RT để giảm thiểu tính toán của server. Khi 1 reques được gọi đến chứa AT, tuỳ dự án thì sẽ chỉ cần kiểm tra xem token có hợp lệ không, hoặc cùng lắm là hit vào cache để kiểm tra. Khi gen ra cặp token mới dùng RT, lúc này mới vào db để xem token có valid ko, user có valid ko. Như vậy, để AT ngắn để trong khoảng thời gian lifetime của token thì chỉ cần check token, còn RT có lifetime dài để người dùng không cần đăng nhập lại
 
Như bạn trên đã trả lời, Access Token ko cũng có thể giải quyết được nhưng giá phải trả là server sẽ phải tính toán nhiều hơn rất nhiều.
 
Nếu bạn nào dùng bên dịch vụ như auth0 hay okta thì sẽ có lẻ để ý hơn về use cases qua scopes offline_access hay là authorization session (nhấn mạnh là authorization).
 
Em cảm ơn hai bác vì câu trả lời chi tiết ạ. Nhưng em vẫn cảm thấy rằng một JWT access token thôi cũng đủ sức làm chuyện này rồi ạ.

VD một scenarios như này
  • Legit User (LU) sau khi login có 1 access token (AT1)
  • Malicious User (MU) đánh cắp được AT1 từ LU
  • LU gửi request gì đó như post một Product mới lên server cùng với AT1
    Nếu AT1 valid, cho LU post một Product mới và cung cấp cho LU một AT mới là AT2
  • MU sau đó cũng sử dụng AT1 (đã bị đánh cắp từ trước) để gửi refresh lên server → AT reuse detected

    Xong rồi revoke AT2 bắt LU login lại và cảnh báo LU

    Đó, theo em thấy thì một mình một token thôi cũng đủ để xử lý vấn đề rồi ạ. Cơ sự gì xin ra 2 thằng riêng biệt AT với RT chi ạ
Chú cũng nhìn thấy đấy thì còn hỏi gì nữa nhỉ?

Cái cơ chế của chú là mỗi lần có request đều phải trả về AT mới, và lưu cái thông tin về AT mới nhất trên DB để verify được những requests từ AT không phải mới nhất. Như thế này sẽ phải lưu và write quá nhiều vào DB. Trong khi nếu dùng RT thì chỉ lâu lâu tạo AT mới thì mới phải lưu thông tin về cái AT mới này thôi. Mỗi request đến server vẫn phải read vào DB để check trước khi cho qua nhưng không phải write nhiều như cách của chú
 

Thống kê chủ đề

Ngày tạo
xuanduy1508,
Người trả lời cuối
motophankhoilon,
Trả lời
76
Lượt xem
16.899
Quay lại
Lên đầu trang