Xác thực người dùng bằng JWT
Cho mình hỏi vấn đề này với ạ. Mình viết một ứng dụng có chức năng người dùng đăng nhập như nhiều sách, bài viết đã giải thích như sau. người dùng sẽ nhập username và password để gửi lên server, server xác thực username và password đó. Nếu ok thì sẽ trả về token, refresh token (dự kiến như vậy), và expire time. sau đó người dùng dùng token đó để access resource trên server. Về phía client mình có những thắc mắc sau.
Dùng điều kiện gì để kiểm tra người dùng đã đăng nhập chưa để hiện thị màn hình đăng nhập khi khởi động app. Có phải chỉ cần kiểm tra trong localstorage (đại loại là vậy) có giá trị access token hay không là đủ? Nếu có thì vào thẳng màn hình chính, nếu chưa thì vào màn hình đăng nhập. Nếu ở trên dùng access token để kiểm tra đã đăng nhập hay chưa thì làm thế nào để kiểm tra access token đó có hợp lệ hay không. Hợp lệ ở đây nghĩa là token chưa expire. Hay là phải gửi request nào đó để kiểm tra có hợp lệ hay không? Vì access token có thời gian expire ngắn nên để ứng dụng sử dụng một cách liên tục không bị gián đoạn và người dùng không phải đăng nhập lại nhiều lần thì làm thế nào để thực hiện như vậy? Mình đang nghĩ tới việc dùng refresh token để lấy lại token mới khi hết hạn. Và lại có nhiều thắc mắc nữa. 3a. Khi nào thì cần lấy lại token mới? trước khi token cũ expire hay sau khi expire? 3b. Làm thế nào để kiểm tra token đó expire hay chưa? Dùng expire time trả về để kiểm tra token đó khi nào hết hạn. Dùng timer hoặc cách gì đó để trước khi expire thì sẽ lấy token mới bằng refresh token rồi cập nhật vào localstorage. 3c. Có phải chỉ cần token chưa expire thì nó luôn luôn có thể truy cập vào server resource không? Nếu user đổi mật khẩu hay thay đổi gì đó ở thiết bị khác thì token này có còn hợp lệ không. Cái này mình chưa hiểu rõ lắm về token. 3d. Làm thế nào để tránh trường hợp người dùng đang mở ứng dụng mà token bị hết hạn dẫn để bị lỗi. Những ứng dụng như Facebook, Zalo… chắc cũng dùng access token để xác thực? Vậy làm thế nào họ có thể duy trì ứng dụng đăng nhập một cách lâu như vậy?
Xin lỗi mình dùng tiếng Anh tiếng Việt lẫn lỗn. Cảm ơn ạ.
1 CÂU TRẢ LỜI
Chào bạn. Mình đã làm, và đang sử dụng + fix một số lỗi liên quan đến JWT, và sử dụng JWT để thực hiện xác thực người dùng. Về câu hỏi thứ nhất của bạn, thì đúng, chỉ cần kiểm tra trong chỗ bạn chỉ định lưu token (access token) để kiểm tra việc người dùng đã đăng nhập hay chưa là đủ. Câu hỏi thứ 2: thường, trong mỗi request gửi lên, thì server đều phải kiểm tra xem cái access token đó có hợp lệ hay không, nếu không hợp lệ thì trả về cho client một chuỗi tuỳ bạn, một status code mặc định (có thể do bạn quyết định status code đó là gì), và, cách kiểm tra thì bạn có thể xem cách JWT verify của từng ngôn ngữ. Như mình dùng nodejs thì có module jsonwebtoken, còn bạn dùng cái gì thì có thể tìm hiểu xem có những module, hoặc cách verify để tự viết ra một cái. Câu hỏi thứ 3: người dùng đúng là không cần phải đăng nhập nhiều lần trong khi access token có thời gian sống ngắn. Bạn có thể handle request gửi lên từ client, tuỳ theo server trả về từng status code bạn đã thiết lập. Ví dụ: khi server trả về status 200, nghĩa là mọi thứ bình thường, request được chấp nhận, xử lý và server trả về dữ liệu liên quan. Còn nếu server trả về 401, nghĩa là bạn chưa đăng nhập, và client sẽ phải gửi thêm một request khác để thực hiện quá trình refresh token, tạo token mới và thực hiện lại request trước đó. Câu hỏi 3a: lấy token mới khi access token cũ hết hạn. Câu hỏi 3b: sẽ kiểm tra thời gian hết hạn của access token. Thường các module hoặc plugin hoặc các thư viện (tuỳ vào việc bạn sử dụng ngôn ngữ nào) sẽ có các function để xác thực và tạo mới token. Cái này bạn cần đọc thêm tài liệu. Câu hỏi 3c: đúng là token chưa hết hạn, thì user luôn có quyền truy cập vào server nguồn. User thay đổi mật khẩu thường không liên quan tới token, trừ khi bạn config việc bắt buộc phải đăng nhập lại sau khi thay đổi mật khẩu (giống facebook làm). 3d: giống câu hỏi thứ 3. Bạn cần phải handle cách server trả về status code và cách client xử lý nó.
Chốt hạ: bạn cần đọc thêm tài liệu trước khi hỏi. Những câu hỏi này đều có sẵn câu trả lời khi bạn tìm hiểu kỹ hơn về json web token. Cảm ơn. Có thắc mắc gì có thể hỏi mình.
Cảm ơn bạn đã trả lời chi tiết. Về phía logic của client mình vẫn đang thắc mắc là dựa vào đâu để mình renew token. chả nhẽ đang dùng ứng dụng mà khi gửi request nếu reponse bị lỗi thì lúc đấy mới renew lại. như vậy thì sau mỗi request đều phải kiểm tra response hả.
@npham đúng rồi. Bản chất của việc xác thực người dùng bằng JWT, chính là việc access token liên tục được gửi kèm theo mỗi request. Vậy nên mỗi request đều phải được kiểm tra để chắc chắn rằng người dùng gửi request đó vẫn còn khả năng truy cập.
Nhưng đúng, bạn có thể cho token auto renew trước khi thời gian hết hạn. Nghĩa là mỗi khi bạn gửi 1 request, bạn chấp nhận phải kiểm tra xem đã gần đến thời gian access token hết hạn chưa. Nếu chưa, thì không gửi refresh token, nếu gần đến thời gian hết hạn (cái này bạn tự định nghĩa) thì sẽ tự động gửi request nhận token mới, như vậy bạn có thể chủ động việc refesh token. Và người dùng không phải chờ đợi nếu token thật sự hết hạn. Nhưng người dùng vẫn phải chờ. Nếu bạn có sử dụng facebook token, mấy cái auto like hay auto comment, bạn sẽ biết rằng, facebook set hạn token là 4h. Bạn có thể test xem