Refresh Token - JWT
Chào các anh chị, hiện tại em đang dùng JWT để xác thực cho web (express + reactjs) Theo như em hiểu thì nó hoạt động như sau:
- Mỗi lần user đăng nhập thì server sẽ tạo access và refresh token (refresh token lưu ở Database) rồi gửi access token và refresh token về client rồi lưu ở local storage của client
- Access token có thời hạn trong thời gian ngắn (ví dụ 10p) để nếu bị mất thì người khác sẽ chỉ truy cập được dữ liệu trong 10p.
- Hết 10p thì web user sẽ dùng refresh token để tạo mới access token để user không phải login lại nhiều lần.
Em có thắc mắc là access token và refresh token để lưu ở local storage nên nếu bị ai đó trộm được refresh token thì họ có thể dùng refresh token đó để gọi mới access token rồi truy cập tài nguyên từ Server => Vậy thì việc ta để access token có thời hạn ngắn hoàn toàn vô ích? Vậy tại sao ta lại cần tới 2 loại token vậy ạ, chỉ cần một loại token vừa dùng dùng để xác thực như access token vừa có thời hạn lâu và lưu ở DB như refresh token, nếu có bị aii đó trộm token thì chỉ cần xóa nó ở DB là được (vì nếu dùng refresh token thì cũng có nguy cơ tương tự)?
Hi vọng được các anh chị giải đáp thắc mắc. Em chân thành cảm ơn.
5 CÂU TRẢ LỜI
Cứ coi như nó chiếm được cả AT và RT, nhưng khi dùng hết time của AT thì nó làm mới cả AT và RT luôn ( AT date mới, còn RT vẫn date như cũ ). Thằng hacker có RT cũ cx có dùng được nữa đâu. Bonus: lưu token vào cookie, ko dùng local storage
Giả sử hacker nó chiếm được AT và RT, nó có thể dùng RT đó để lấy AT và RT mới mà anh nhỉ?
@TranTranTran đúng, nhưng chỉ cần user là ng đổi rt trước, hoặc chỉ cần user login lại là có rt mới ngay, khi đó rt của hack là vô dụng
Thực ra để bảo vệ refresh token cũng không khó như bạn nghĩ đâu đây là 2 cách mình thường làm"
- Thêm xác thực app-id, api-key (có thể thêm cơ chế xác thực vào middleware) kiểm tra app-id đó mà server cấp cho front-end, có thể hash lại và gửi thông qua body. Nếu qua header thì dùng sha256 và lưu salt ở server bạn.
- Kiểm tra ip đc cấp phép không,
- Bonus: Thường thì truy cập qua browser nếu có request sẽ có User-Agent ở header. Ví dụ : " Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/123.45 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/123.45" .Kiểm tra xem browser gì, nếu ko thì sẽ là từ code, postman hay cURL thì ban luôn refresh token đó
Thêm xác thực app-id, api-key (có thể thêm cơ chế xác thực vào middleware) kiểm tra app-id đó mà server cấp cho front-end, có thể hash lại và gửi thông qua body. Nếu qua header thì dùng sha256 và lưu salt ở server bạn.
với app-id, api-key được lưu ở local storage thì vẫn lấy được mà bạn
Kiểm tra ip đc cấp phép không,
cái này là filter theo IP rồi, giờ dịch vụ public cho cộng đồng sử dụng thì làm sao dùng cách này được, chỉ hiệu quả ở 1 số trường hợp
Bonus: Thường thì truy cập qua browser nếu có request sẽ có User-Agent ở header. Ví dụ : " Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/123.45 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/123.45" .Kiểm tra xem browser gì, nếu ko thì sẽ là từ code, postman hay cURL thì ban luôn refresh token đó
Postman cũng fake được User-Agent, điều gì bạn đảm bảo nó k phải từ ứng dụng khác ngoài trình duyệt
Theo e với chức năng xác thực thì có thể set cookies samesite và tùy yêu cầu để strict hay lax. Nếu bác có kinh nghiệm tốt hơn về bảo mật refresh token thì mong bác chỉ giáo với 😁
Lập luận của bạn đúng. Tuy nhiên, bạn có thể hình dung như thế này
RT và AT là 2 cái chìa khóa cửa nhà bạn, AT luôn mang theo người, RT để ở nhà để backup. AT thì bạn luôn mang theo người và đi ra ngoài thì khả năng bị lộ là cao hơn cho nên cần để thời gian có hiệu lực ngắn để kẻ gian chỉ lợi dụng đến khi AT hết hạn thì thôi. RT chỉ thực hiện chức năng backup khi AT có vấn đề. => Mỗi loại token thì thực hiện đúng mục đích của nó
Hi mn, mình có tìm hiểu và nghiên cứu một tí về refresh token JWT, và cách mình đang làm như sau:
Giải pháp này bao gồm hai lớp mã hóa chính: Tạo khóa AES, Mã hóa RSA để bảo vệ khóa AES. Mã hóa AES để mã hóa mã thông báo làm mới thực tế và ID thiết bị. Gửi các thông tin đã được mã hoá về server. Máy chủ sẽ giải mã khóa, sau đó decode refresh token, xác thực các thông tin có trùng khớp không, nếu hợp lệ sẽ tạo mã mới.
Mọi người có thể đọc thêm blog này để hiểu rõ hơn flow cũng như những điểm về security nhé. https://blog.thnkandgrow.com/implementing-a-custom-jwt-refresh-token-strategy-with-aes-and-rsa-encryption/
Haha. Mới hôm qua đi phỏng vấn gặp trúng JWT này. Để lưu lại mai mốt đọc.