Tại sao cần Refresh Token? Bạn đã biết cách lưu trữ Refresh Token và Access Token an toàn trong trình duyệt chưa?

Tại sao cần Refresh Token? Bạn đã biết cách lưu trữ Refresh Token và Access Token an toàn trong trình duyệt chưa?

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Mọi người thường nói đùa rằng regex là ngôn ngữ của người ngoài hành tinh. Ai mà viết được regex thì họ có năng lực của một người ngoài Trái Đất. Nói đùa vậy thôi chứ thực chất là chỉ ý regex thật khó hiểu.

    Tình cờ mình biết đến một trang web dạy chúng ta regex từng bước một. Trong quá trình học chúng ta cần tương tác với hàng chục câu hỏi từ đơn giản đến nâng cao để từng bước học cách sử dụng "ngôn ngữ ngoài hành tinh" này.

    regexlearn.com

    » Xem thêm
  • Tin vui đầu ngày. Github vừa công bố rộng rãi GitHub Models đến tất cả mọi người. Nếu còn nhớ cách đây hơn 2 tháng trước, Github có chương trình đăng ký dùng thử các models của LLMs, và trường hợp của mình thì phải một tháng sau mới được duyệt cho dùng. Thì giờ đây họ đã cho mọi người dùng Github có quyền truy cập vào rồi, không cần phải đăng ký gì nữa 🥳

    GitHub Models đang là phao cứu sinh cho mình trong khi xây dựng trang blog này 😆

    GitHub Models is now available in public preview | Github Blog

    » Xem thêm
  • Hôm trước mình thấy repository này dùng TauriSvelte để viết lại ứng dụng kiểu như là Task Manager trên Window hay Monitor trên Mac á. Tò mò tải về xem thử thì bất ngờ thứ nhất là dung lượng rất nhỏ, chỉ vài MB. Tiếp theo là tốc độ khởi động cũng rất nhanh mà ứng dụng cũng rất mượt nữa chứ 🫣

    Abdenasser/neohtop

    » Xem thêm

Vấn đề

Lưu ý: Phạm vi bài viết này nói trong khuôn khổ Oauth2 được mô tả tại rfc6749.

Xin chào mọi người, chuyện là mấy ngày hôm nay tôi có đọc một vài tranh luận của mọi người trên mạng về vấn đề sử dụng access token (AT) và refresh token (RT) sao cho hợp lý. Có người thì bảo chỉ cần triển khai AT thôi là đủ, có người thì bảo cần thêm cả RT 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ả AT và RT 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 và Refresh Token là gì?

Đầu tiên cho những ai chưa biết, AT 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 AT, bạn lưu lại mã AT đó 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 AT và RT 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 AT và RT rất là phổ biến.

Còn RT là đoạn mã được dùng để yêu cầu cấp một mã AT mới. Chúng ta hãy làm rõ vấn đề tại sao lại cần phải dùng RT?

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ã AT để đạ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ã AT 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ã AT mà dựa vào mã AT đó có thể thay mặt người dùng để sử dụng được hệ thống.

Do đó, đôi khi việc có mã AT 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ã AT 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ã AT 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ã AT lại, ví dụ như mã AT 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ã AT 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.

jwt

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 tôi 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 RT hay như thế nào. Vì tôi biết có nhiều hệ thống không cần triển khai đến RT 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 AT và RT.

Có một vài lý do để AT 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 AT quá dài, khi bị lộ AT 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 AT đã 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ã AT, lúc đó nếu muốn vô hiệu hóa những mã AT 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ã AT đã được tạo ra.

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

  • Rút ngắn thời gian tồn tại của AT, khi AT bị hết hạn thì sử dụng RT để lấy mã AT 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ã RT và kí mã AT để đạ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. RT thường được lưu trữ ở máy chủ ủy quyền phục vụ cho mục đích cấp mã AT mới. Còn mã AT đượ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 AT, nếu muốn chấm dứt phiên chỉ đơn giản là vô hiệu hóa mã RT trên máy chủ ủy quyền.

Sau khi hiểu được những lý do trên thì việc sinh ra RT giúp giải quyết được một vài hạn chế khi chỉ sử dụng mỗi AT. Nhưng như vậy nếu mã AT hoặc RT 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.

Xem tiếp phần 2: Tại sao cần Refresh Token? Bạn đã biết cách lưu trữ Refresh Token và Access Token an toàn trong trình duyệt chưa? Phần 2 .

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (4)

Nội dung bình luận...
Avatar
Tuan Nguyen1 năm trước
Giả sử rằng: Nếu bị lộ Refresh Token thì sao ? Hacker có thể dùng Refresh Token để "xin" Access Token mới và từ đó sử dụng Access Token để truy cập vào những nội dung không mong muốn. Trong mỗi request được gửi lên (giả sử token được lưu trong cookie hoặc một nơi nào đó) thì request đó luôn bao gồm một cặp Refresh Token + Access Token. Vậy nếu bị "nhảy mất" cái request đó thì có đảm bảo rằng Access Token đó sẽ an toàn (Expired ư ? => Đã có Refresh Token lo hết ). Từ đó khẳng định rằng "nên thời gian càng ngắn thì nguy cơ access token khi bị lộ càng ít rủi ro." khá là thiếu căn cứ.
Trả lời
Avatar
Xuân Hoài Tống1 năm trước
Bonus: AT sinh ra để giảm thiểu gánh nặng trên máy chủ tài nguyên, việc còn lại là gánh nặng của máy chủ ủy quyền nên RT phải làm chặt chẽ hơn. Cụ thể phải từ RT để lấy AT nên AT tồn tại càng ngắn thì càng tốt, bắt buộc phải qua máy chủ ủy quyền để kiểm tra gian lận. Dĩ nhiên là khoảng thời gian "ngắn" đó chỉ mang tính tương tối cho các dự án.
Avatar
Xuân Hoài Tống1 năm trước
Trường hợp bạn nêu trên thì đúng là "thiếu căn cứ" theo như bạn nói. Nhưng đó là trong trường hợp RT + AT được gửi lên trong "mỗi" request. Thực tế thì bạn không nhất thiết phải gửi lên RT trong các yêu cầu đến máy chủ tài nguyên. RT chỉ nên được gửi đến máy chủ ủy quyền (nhiều người hay bị nhầm giữa máy chủ tài nguyên & máy chủ ủy quyền, cũng có thể do máy chủ tài nguyên + ủy quyền là một) để xin AT mới. Thế nên có một vài lý do để bảo mật RT hơn AT để hạn chế RT bị rò rỉ. Nhưng phải nói khi AT bị đánh cắp thì RT bị "bay" theo cũng rất lớn. Chính vì thế chúng ta phải có biện pháp mạnh trên máy chủ ủy quyền để phát hiện RT bị đánh cắp. Vấn đề này cũng có nhiều giải pháp rồi bạn có thể tham khảo các nguồn trên GG, tôi đang tiếp tục series bài viết về AT & RT chỉ là chưa sắp xếp được thời gian, khi nào có mong bạn tiếp tục xem có vấn đề gì cần làm sáng tỏ hơn nữa không.
Avatar
Đình Trung2 năm trước
@gif [XejFQNGS90SvaITLRZ] Mấy tháng rồi nhỉ
Trả lời
Avatar
Long Domi2 năm trước
@gif [10JhviFuU2gWD6] Sắp có từ một tháng trước
Trả lời
Avatar
Linh Trịnh Mạnh2 năm trước
Ủa phần tiếp theo đâu anh ơi đang cuốn mà hóng mãi không thấy
Trả lời
Avatar
Xuân Hoài Tống2 năm trước
Sắp có rồi bạn 😅