Câu hỏi về cách lưu Refresh Token, và quy trình của token và refresh token
Đầu tiên thì em xin chào mọi người đã vào đây đọc để giải đáp cho em
Sau nhiều ngày search google và tìm các code trên github để xem thì đây là những gì em hiểu về token và refresh token, nếu sai đoạn nào mong mọi người góp ý ạ:
- Sau khi login thành công server sẽ trả cho client 1 cái token và refresh token, client sẽ cất nó ở localstorage hoặc cookie (thường sẽ là cookie vì nó bảo mật hơn chút).
- Mỗi lần gửi request lên server, client sẽ gửi kèm token, nhiệm vụ lúc này của server là kiểm tra tính hợp lệ và tính sống còn của token
- Nếu Token hợp lệ và chưa chết thì ok, nó đã được thông qua. Còn nếu token không tồn tại hoặc hết hạn thì client sẽ gửi request lên server đòi token nhờ refresh token.
- Trong trường hợp refresh token không hợp lệ hoặc hết hạn thì xong, bạn phải login lại.
Về việc lưu refresh token: Rất nhiều bài trên mạng đưa ra cách là nên lưu DB.
- Như vậy em có 1 thắc mắc sau là khi token chết, thì làm cách nào để server kiểm tra tính hợp lệ của refresh token?
- Sau khi suy nghĩ thì em đưa ra câu hỏi tiếp là liệu refresh token vừa được client lưu ở local giống token và vừa được lưu trong DB?
- Nếu như nó được lưu ở client rồi thì cần gì phải lưu ở DB trong khi server vẫn có thể kiểm tra tính hợp lệ và độ sống còn của nó giống thằng Token?
- Và nếu như nó cũng được lưu như token thì chẳng phải token và refresh token nó gần như là 1 hay sao?
Bên trên là những câu hỏi trong đầu em, mong mọi người giải đáp ạ
1 ANSWERS
câu trả lời ko mang tính bao hàm tất cả mọi trường hợp
Đoạn tìm hiểu của e về access token và refresh token là đúng đó e, đó cũng là những gì cơ bản nhất khi nói về access và refresh token
Về việc lưu refresh token trong DB
Như vậy em có 1 thắc mắc sau là khi token chết, thì làm cách nào để server kiểm tra tính hợp lệ của refresh token?
Sau khi access token expired thì e query lại lên server dùng refresh token, server nó sẽ check trong DB nếu cái refresh token của e match thì trả về access token mới cho e. (nhằm đảm bảo token đó đc generated bởi server, đc lưu lại trong DB của server)
Sau khi suy nghĩ thì em đưa ra câu hỏi tiếp là liệu refresh token vừa được client lưu ở local giống token và vừa được lưu trong DB?
Đó như bên trên a đã nói lúc server check refresh token của e trong DB nếu ko match với phía client của e gửi lên thì bắt login lại
Nếu như nó được lưu ở client rồi thì cần gì phải lưu ở DB trong khi server vẫn có thể kiểm tra tính hợp lệ và độ sống còn của nó giống thằng Token?
Câu này hay ). Một trong những mục đích người ta thường dùng khi lưu token (cả access token và refresh token) trong DB đó là để có thể revoke token bất kì lúc nào (huỷ bỏ token). Ví dụ như Facebook cho login trên nhiều thiết bị, mỗi thiết bị có 1 token, và mình muốn logout khỏi thiết bị nào thì revoke token của thiết bị đó. Lưu token trong DB thì cho phép ta quản lý được tokens (số lượng, ai sở hữu,...)
Và nếu như nó cũng được lưu như token thì chẳng phải token và refresh token nó gần như là 1 hay sao
Không phải . Access token là access token, refresh token là refresh token. E ko thể dùng Refresh token để truy cập protected resources được, và đó ko phải bản chất của refresh token.
Việc lưu token ở đâu là tuỳ thuộc vào use case của e và e chọn 1 cách hợp lý nhất cho project của mình.
Token để ở cookie muốn bảo mật thì set httpOnly=true
(ko thể đc truy cập bằng javascript), set thêm secure=true
(chỉ đc dùng nếu web load bằng https), set thêm sameSite
nữa thì cũng thêm 1 lần bảo mật ở phía client. Đây cũng là cách a thấy mọi người dùng nhiều hơn cả
Lưu token ở trong DB sẽ cho ta thêm 1 số tính năng nữa như revoke token bất kì lúc nào mong muốn (trường hợp refresh token của e mà "sống" lâu quá thì đây cũng có thể là 1 giải pháp), hay để check chính xác là refresh token gửi bởi client match với DB phía server (để chắc chắn token đc generate bởi server và đc lưu vào DB cẩn thận). Nếu ko lưu token vào DB thì mỗi lần login mình sẽ "sign" và trả về access + refresh token về cho user, lần tới user request dùng các token đó thì mình vẫn check đc là nó có hợp lệ hay ko, nhưng mình ko thể biết được ngoài kia hiện tại có bao nhiêu token của user, loại nào bao nhiêu, account nào sở hữu nhiều tokens,.... Đương nhiên việc lưu token trong DB này sẽ thêm việc cho server của e (e phải quản lý cả tokens), mà token là thứ user tạo ra liên tục, 1 account có thể có hàng chục/trăm token, nên nếu ko có cơ chế để remove unused/expired token thì DB của e lại overload (yes, lại thêm việc) .
Câu trả lời rất có tâm.
@maitrungduc1410 anh Mình có khác trả lời clear, dễ hiểu thực sự
Cám ơn bạn @maitrungduc1410 đã có câu trả lời rất chi tiết và tường tận.
Cám ơn bạn @toilahuong đã tạo ra một câu hỏi lý thú và nhiều cái thắc mắc hay giúp ích được cho mọi người
Đọc clear thật, bao nhiều khúc mắc bấy lâu được gỡ rối hết :>
Sau khi access token expired thì e query lại lên server dùng refresh token, server nó sẽ check trong DB nếu cái refresh token của e match thì trả về access token mới cho e. (nhằm đảm bảo token đó đc generated bởi server, đc lưu lại trong DB của server)
cái đoạn này e chưa hiểu lắm, lấy gì để query vậy a, chính accessToken hết hạn để verify với RT trên db đúng k a
@anhtuanlee ban đầu sau khi login thì server trả về cho client 2 token: 1 là access token, 1 là refresh token.
Trong suốt quá trình call api để lấy data e sẽ dùng access token
Khi access token hết hạn, thì k cần đến nó nữa, mà e lấy refresh token kia call api để lấy access token mới (server sẽ có 1 api riêng dành cho việc này). Server trả về access token mới
@maitrungduc1410 cám ơn anh nhen, tức là khi accessToken hết hạn thì mình gửi RT lên, và check nó với db có same không khi đó mới trả về, và clear đi cái cũ, set cái mới vào db đúng k a
@anhtuanlee uk kiểu vậy e ạ
thế trường hợp refresh token trong db hết hạn thì cơ chế nào tốt nhất để xoá bỏ ạ, e đang nghĩ đến việc chạy cronjob nhưng thấy không được tốt lắm
@Duc_Thang_2000 sorry e a bỏ lỡ comment này
a thấy việc remove token bị hết hạn này thường là low-priority (thường thôi chứ ko phải tất cả trường hợp)
và cơ chế remove thì có nhiều cách, ở đây a nghĩ nhanh 2 cách:
- đơn giản nhất là chạy cronjob
- hoặc ko thì chờ lần tiếp theo user login vào thì xoá token cũ và tạo cái mới (cái này ưu điểm là ko chạy cronjob mà chỉ làm với những user thực sự quay lại, nhược điểm là nhiều user ko quay lại thì tốn resource db)
@maitrungduc1410: Anh ơi, vậy refresh token thường lưu ở cả DB và client đúng không ạ ?
@TranChien2112 về cách lưu thì a thấy mọi người có rất nhiều cách lưu khác nhau. 1 trong những cách phổ biến là cả refresh + access token lưu ở client (local storage).
khi e cần lưu ở db thì e tự đặt câu hỏi:
- xem liệu e có cần quản lý số lượng token hay ko: có cần biết mỗi user đã tạo bao nhiêu token? bao nhiêu cái sắp hết hạn..., token nào ăn với device nào?
- có cần revoke token hay ko? ...
@maitrungduc1410 e cảm ơn a nha