Sử dụng JWT đã hết hạn sẽ khiến các thao tác không thành công. Như bạn đã thấy ở trên, chúng tôi được cho biết mã thông báo có hiệu lực trong bao lâu cho đến khi expires_in
. Giá trị này thường là 1200 giây hoặc 20 phút. Mã thông báo hết hạn không được làm mới. Chúng tôi chỉ tìm nạp một mã thông báo mới và chuyển mã đó tới Live Experience SDK
Bạn cần tự theo dõi ngày hết hạn JWT. Một cách là đặt bộ hẹn giờ trong ứng dụng của bạn để tìm nạp mã thông báo mới sau 1200 giây. Đây là một bộ đếm thời gian trong Swift.
Timer.scheduledTimer[timeInterval: expires, target: self, selector: #selector[fetchToken], userInfo: nil, repeats: false]
Một cách khác là tính thời gian hết hạn bằng cách thêm 1200 giây vào thời gian hệ thống hiện tại khi mã thông báo được truy xuất. Vì vậy, nếu thời gian bạn lấy mã thông báo là 10. 00 thời gian hết hạn sẽ là 10. 20. Một ví dụ về điều này trong Swift trông giống như. let expireTime = Date[].addingTimeInterval[expires]
Sau đó, bạn so sánh thời gian hiện tại với thời gian hết hạn để xem mã thông báo đã hết hạn chưa
Hai mươi phút là một khoảng thời gian dài và bạn có thể khởi chạy ứng dụng của mình nhiều lần trong khoảng thời gian đó. Lưu trữ mã thông báo của bạn trong bộ lưu trữ liên tục cho phép mã này tồn tại sau khi thoát ứng dụng. Dưới đây là một ví dụ về lưu trữ mã thông báo và thời gian hết hạn của nó trong bộ lưu trữ liên tục với Swift.
UserDefaults.standard.set[token, forKey: "LXtoken"]
UserDefaults.standard.set[expireTime, forKey: "tokenExpireTime"]
Xác định xem JWT đã hết hạn trong ứng dụng khách mà không yêu cầu bí mật hay chưa, điều này chỉ dành cho ứng dụng khách sử dụng và không nhằm mục đích xác thực an toàn cho JWT. Chỉ như một phương pháp thuận tiện để tránh cuộc gọi mạng nếu JWT đã chỉ ra rằng nó đã hết hạn
Cài đặt
npm install jwt-check-expiration
Cách sử dụng
Xác định xem JWT đã hết hạn trong ứng dụng khách khi không cần xác thực và bạn không muốn tiết lộ bí mật
Quan trọng
Chỉ sử dụng điều này khi bảo mật không quan trọng, chẳng hạn như khi bạn chỉ muốn lưu yêu cầu mạng trước khi phải làm mới mã thông báo. Trong trường hợp JWT đã được sửa đổi và hết hạn không hợp lệ, trường hợp xấu nhất là bạn sẽ thực hiện một yêu cầu mạng không cần thiết, yêu cầu này sẽ làm mới mã thông báo trong quá trình thiết lập của bạn
Mã thông báo JWT không bao giờ hết hạn sẽ nguy hiểm nếu mã thông báo bị đánh cắp thì ai đó luôn có thể truy cập dữ liệu của người dùng
Trích dẫn từ JWT RFC
Yêu cầu "hết hạn" [thời gian hết hạn] xác định thời gian hết hạn vào hoặc sau đó JWT KHÔNG ĐƯỢC chấp nhận để xử lý. Quá trình xử lý yêu cầu "hết hạn" yêu cầu ngày/giờ hiện tại PHẢI trước ngày/giờ hết hạn được liệt kê trong yêu cầu "hết hạn"
Vì vậy, câu trả lời là hiển nhiên, hãy đặt ngày hết hạn trong yêu cầu exp
và từ chối mã thông báo ở phía máy chủ nếu ngày trong yêu cầu exp
trước ngày hiện tại
Khá dễ phải không?
Vấn đề là các ứng dụng di động không bao giờ hết hạn, chẳng hạn như mọi người có thể mở lại APP sau một tháng mà không cần phải đăng nhập lại
Đối với ứng dụng web. Nếu bạn đặt thời gian hết hạn là 1 tuần, không sử dụng mã thông báo trong 1 tuần. Sử dụng chưa đầy một tuần và nhận mã thông báo mới trước khi mã thông báo cũ hết hạn. Ví dụ: yêu cầu trình duyệt gửi yêu cầu đổi mã thông báo mới vào ngày thứ sáu. Điều này không khác với khái niệm thông thường về phiên và cookie
Theo đó, về phía máy chủ, hãy tạo một restful API tên là
/token/extend
sẽ trả về một mã thông báo mới nếu được cung cấp một mã thông báo hợp lệNếu người dùng không sử dụng ứng dụng của bạn trong một tuần, lần tới khi họ truy cập ứng dụng của bạn, họ sẽ phải đăng nhập lại và điều này ổn và được chấp nhận rộng rãi
Đối với ứng dụng di động gốc. bạn có thể sử dụng cách giải thích tương tự ở trên, nhưng đó không phải là cách Ứng dụng dành cho thiết bị di động hoạt động hiện nay, e. g. , người dùng có thể mở Ứng dụng Facebook sau một tháng không sử dụng và lần sau khi mở Ứng dụng không cần đăng nhập lại
Một giải pháp là thêm xác nhận quyền sở hữu đối tượng có tên
aud
vào mã thông báo JWT, chẳng hạn, sử dụng tải trọng như{"sub": "username", "exp": "2015-11-18T18:25:43.511Z", "aud":"iPhone-App"}
. Về phía máy chủ, nếu mã thông báo có trườngaud
có giá trị
1 thì hãy bỏ qua xác nhận quyền sở hữuUserDefaults.standard.set[token, forKey: "LXtoken"] UserDefaults.standard.set[expireTime, forKey: "tokenExpireTime"]
exp
, để mã thông báo có
1 không bao giờ hết hạn. Tuy nhiên, bạn vẫn có thể thu hồi loại token này bằng cách sử dụng các phương pháp được mô tả trong Phần 2UserDefaults.standard.set[token, forKey: "LXtoken"] UserDefaults.standard.set[expireTime, forKey: "tokenExpireTime"]
Một giải pháp khác là sử dụng mã thông báo làm mới không bao giờ hết hạn để tìm nạp mã thông báo JWT mới hết hạn. Vì mã thông báo làm mới không bao giờ hết hạn nên điều gì sẽ xảy ra nếu điện thoại của bạn bị đánh cắp?
Thông thường, để phân biệt với các mã thông báo làm mới khác nhau của một người dùng, cách tốt nhất là đặt tên thiết bị cụ thể vào mã thông báo làm mới, ví dụ:
4, để khi người dùng muốn thu hồi mã thông báo làm mới, họ có thể biết mã thông báo làm mới này đang được sử dụng.UserDefaults.standard.set[token, forKey: "LXtoken"] UserDefaults.standard.set[expireTime, forKey: "tokenExpireTime"]
2. Cách thu hồi mã thông báo JWT
Đôi khi người dùng cần thu hồi mã thông báo, chẳng hạn như nhấp vào nút đăng xuất hoặc thay đổi mật khẩu
Giả sử rằng mỗi người dùng có nhiều thiết bị, giả sử, một trình duyệt, một ứng dụng iPhone gốc và một ứng dụng Android gốc
Có ba cách
Thay đổi khóa bí mật
Điều này sẽ thu hồi tất cả các mã thông báo của tất cả người dùng, điều này không được chấp nhận
Làm cho mỗi người dùng có bí mật của riêng mình và chỉ thay đổi bí mật của một người dùng được chỉ định
Bây giờ phụ trợ RESTful không còn trạng thái nữa. Mỗi khi có yêu cầu, máy chủ cần truy vấn cơ sở dữ liệu để lấy bí mật của người dùng
Để có hiệu suất tốt hơn, hãy lưu trữ các cặp
exp
0 trong Redis thay vì MySQL, sử dụngexp
1 làm khóa vàexp
2 làm giá trịCách này sẽ thu hồi tất cả các mã thông báo của một người dùng, tốt hơn nhiều, nhưng vẫn chưa đủ tốt
Lưu trữ mã thông báo JWT đã thu hồi trong Redis
Sử dụng mã thông báo làm khóa và giá trị luôn là boolean
exp
3Mã thông báo sẽ chỉ được lưu trữ trong một khoảng thời gian cụ thể, đó là thời gian trong yêu cầu của
exp
, sau thời gian hết hạn, mã thông báo sẽ bị xóa khỏi RedisCách này chỉ thu hồi một mã thông báo tại một thời điểm, hoàn hảo
Để biết thêm chi tiết, vui lòng tham khảo blog này, Sử dụng Redis để thu hồi Mã thông báo được tạo từ jsonwebtoken
Đề xuất được hoan nghênh, vui lòng sửa cho tôi nếu tôi sai
3. Cách sử dụng mã thông báo JWT một cách an toàn
Đầu tiên, luôn sử dụng HTTPS để đảm bảo việc truyền mã thông báo JWT qua mạng được an toàn. Bằng cách sử dụng HTTPS, không ai có thể đánh hơi mã thông báo JWT của người dùng qua mạng
Thứ hai, đảm bảo mã thông báo JWT được lưu trữ an toàn trên Android, iOS và trình duyệt của người dùng
- Đối với Android, lưu trữ mã thông báo trong KeyStore
- Đối với iOS, lưu trữ mã thông báo trong KeyChain
- Đối với trình duyệt, hãy sử dụng cookie
exp
5 vàexp
6. bánh quy. Cờexp
5 bảo vệ cookie khỏi bị JavaScript truy cập và ngăn tấn công XSS. Cờexp
6 sẽ chỉ cho phép gửi cookie đến máy chủ qua kết nối HTTPS
Miễn là chúng tôi làm cho trình duyệt, thiết bị người dùng và truyền mã thông báo an toàn, cơ chế thu hồi mã thông báo không còn cần thiết nữa. Chúng tôi vẫn có thể giữ các dịch vụ RESTful của mình ở trạng thái không trạng thái