JWT (JSON Web Token) tự động kéo dài hết hạn


509

Tôi muốn triển khai xác thực dựa trên JWT cho API REST mới của chúng tôi. Nhưng vì hết hạn được đặt trong mã thông báo, có thể tự động kéo dài nó không? Tôi không muốn người dùng cần đăng nhập sau mỗi X phút nếu họ chủ động sử dụng ứng dụng trong khoảng thời gian đó. Đó sẽ là một thất bại lớn của UX.

Nhưng việc kéo dài thời gian hết hạn sẽ tạo ra một mã thông báo mới (và mã thông báo cũ vẫn còn hiệu lực cho đến khi hết hạn). Và việc tạo mã thông báo mới sau mỗi yêu cầu nghe có vẻ ngớ ngẩn với tôi. Âm thanh giống như một vấn đề bảo mật khi có nhiều hơn một mã thông báo hợp lệ cùng một lúc. Tất nhiên tôi có thể vô hiệu hóa cái cũ đã sử dụng bằng danh sách đen nhưng tôi sẽ cần lưu trữ mã thông báo. Và một trong những lợi ích của JWT là không lưu trữ.

Tôi tìm thấy cách Auth0 giải quyết nó. Họ không chỉ sử dụng mã thông báo JWT mà còn sử dụng mã thông báo làm mới: https://docs.auth0.com/refresh-token

Nhưng một lần nữa, để thực hiện điều này (không có Auth0) tôi cần lưu trữ mã thông báo làm mới và duy trì hết hạn. Lợi ích thực sự sau đó là gì? Tại sao không chỉ có một mã thông báo (không phải JWT) và giữ hết hạn trên máy chủ?

Có những lựa chọn khác? Là sử dụng JWT không phù hợp cho kịch bản này?


1
Trên thực tế có lẽ không có vấn đề bảo mật nào với nhiều mã thông báo hợp lệ cùng một lúc ... Thực sự có vô số mã thông báo hợp lệ ... Vậy, tại sao lại có mã thông báo làm mới? Tôi sẽ tạo lại chúng sau mỗi yêu cầu, nó thực sự không phải là một vấn đề.
maryo

1
Đối với SPA, hãy kiểm tra bài đăng trên blog của tôi: blog.wong2.me/2017/02/20/refresh-auth0-token-in-spa
wong2

2
@maryo Tôi nghĩ rằng việc có (có khả năng) hàng trăm hoặc hàng ngàn JWT hợp lệ không được sử dụng ngoài đó tại bất kỳ thời điểm nào sẽ làm tăng dấu vết tấn công của bạn và là một rủi ro bảo mật. Trong tâm trí của tôi, JWT nên được phát hành một cách cẩn thận vì chúng được truy cập mã thông báo bằng chìa khóa vào lâu đài theo cách thức.
java-nghiện602

Câu trả lời:


590

Tôi làm việc tại Auth0 và tôi đã tham gia vào việc thiết kế tính năng làm mới mã thông báo.

Tất cả phụ thuộc vào loại ứng dụng và đây là cách tiếp cận được đề xuất của chúng tôi.

Ứng dụng web

Một mô hình tốt là làm mới mã thông báo trước khi nó hết hạn.

Đặt hết hạn mã thông báo thành một tuần và làm mới mã thông báo mỗi khi người dùng mở ứng dụng web và cứ sau một giờ. Nếu người dùng không mở ứng dụng trong hơn một tuần, họ sẽ phải đăng nhập lại và đây là ứng dụng web UX chấp nhận được.

Để làm mới mã thông báo, API của bạn cần một điểm cuối mới nhận JWT hợp lệ, chưa hết hạn và trả về cùng JWT đã ký với trường hết hạn mới. Sau đó, ứng dụng web sẽ lưu trữ mã thông báo ở đâu đó.

Ứng dụng di động / bản địa

Hầu hết các ứng dụng gốc đều đăng nhập một lần và chỉ một lần.

Ý tưởng là mã thông báo làm mới không bao giờ hết hạn và nó có thể được trao đổi luôn lấy JWT hợp lệ.

Vấn đề với mã thông báo không bao giờ hết hạn là không bao giờ có nghĩa là không bao giờ. Bạn làm gì nếu bị mất điện thoại? Vì vậy, nó cần được người dùng nhận dạng bằng cách nào đó và ứng dụng cần cung cấp một cách để thu hồi quyền truy cập. Chúng tôi đã quyết định sử dụng tên của thiết bị, ví dụ: "iPad của maryo". Sau đó, người dùng có thể truy cập ứng dụng và thu hồi quyền truy cập vào "iPad của maryo".

Một cách tiếp cận khác là thu hồi mã thông báo làm mới trên các sự kiện cụ thể. Một sự kiện thú vị là thay đổi mật khẩu.

Chúng tôi tin rằng JWT không hữu ích cho các trường hợp sử dụng này vì vậy chúng tôi sử dụng một chuỗi được tạo ngẫu nhiên và chúng tôi lưu trữ nó về phía chúng tôi.


42
Đối với cách tiếp cận được đề xuất cho các ứng dụng web, nếu mã thông báo có giá trị trong một tuần, chúng tôi không quan tâm đến việc ai đó chặn mã thông báo và sau đó có thể sử dụng nó trong một thời gian dài như vậy? Tuyên bố miễn trừ trách nhiệm: Tôi hoàn toàn không biết tôi đang nói về điều gì.
dùng12121234

30
@wbeange có đánh chặn là một vấn đề, ngay cả với cookie. Bạn nên sử dụng https.
Jose F. Romaniello

15
@ JoséF.Romaniello Trong ví dụ ứng dụng web của bạn, mọi thứ đều có ý nghĩa với tôi ngoại trừ việc phải lưu trữ mã thông báo. Tôi nghĩ rằng vẻ đẹp của JWT là xác thực không trạng thái - có nghĩa là ứng dụng web KHÔNG phải lưu trữ mã thông báo khi được ký. Tôi nghĩ rằng máy chủ chỉ có thể kiểm tra tính hợp lệ của mã thông báo, đảm bảo rằng nó trong thời hạn hết hạn và sau đó phát hành mã thông báo JWT được gia hạn. Bạn có thể vui lòng giải thích về điều này? Có lẽ tôi chưa hiểu JWTs đủ.
Lo-Tan

7
Hai câu hỏi / mối quan tâm: 1- Trường hợp ứng dụng web: tại sao mã thông báo hết hạn không được phép làm mới? Giả sử chúng tôi đặt hết hạn ngắn (1 giờ) và thực hiện các cuộc gọi gia hạn đến máy chủ phụ trợ khi mã thông báo hết hạn, như bạn đã nói. 2- Có mối quan tâm bảo mật nào với việc lưu trữ mật khẩu băm (với muối ngẫu nhiên) trong mã thông báo không? Ý tưởng là nếu nó ở đó, máy chủ phụ trợ có thể kiểm tra mật khẩu được lưu trong DB khi được yêu cầu gia hạn và từ chối yêu cầu nếu mật khẩu không khớp. Điều này sẽ bao gồm thay đổi mật khẩu ứng dụng Di động / Bản địa, cho phép giải pháp được mở rộng cho trường hợp sử dụng Di động.
psamaan

8
-1 Việc hiển thị API công khai mà ký lại một cách mù quáng bất kỳ mã thông báo nào để kéo dài thời gian xác thực của nó là không tốt. Bây giờ tất cả các mã thông báo của bạn có thời hạn sử dụng vô hạn hiệu quả. Hành động ký mã thông báo phải bao gồm kiểm tra xác thực phù hợp cho từng và mọi khiếu nại được thực hiện trong mã thông báo đó tại thời điểm ký.
Phil

69

Trong trường hợp bạn tự xử lý auth (nghĩa là không sử dụng nhà cung cấp như Auth0), cách sau có thể hoạt động:

  1. Phát hành mã thông báo JWT với thời hạn tương đối ngắn, giả sử 15 phút.
  2. Ứng dụng kiểm tra ngày hết hạn của mã thông báo trước khi bất kỳ giao dịch nào yêu cầu mã thông báo (mã thông báo chứa ngày hết hạn). Nếu mã thông báo đã hết hạn, trước tiên, nó sẽ yêu cầu API 'làm mới' mã thông báo (việc này được thực hiện trong suốt cho UX).
  3. API nhận được yêu cầu làm mới mã thông báo, nhưng trước tiên hãy kiểm tra cơ sở dữ liệu người dùng để xem cờ 'reauth' đã được đặt đối với hồ sơ người dùng đó chưa (mã thông báo có thể chứa id người dùng). Nếu cờ có mặt, thì việc làm mới mã thông báo bị từ chối, nếu không thì mã thông báo mới được phát hành.
  4. Nói lại.

Cờ 'reauth' trong phần phụ trợ cơ sở dữ liệu sẽ được đặt khi, ví dụ, người dùng đã đặt lại mật khẩu của họ. Cờ sẽ bị xóa khi người dùng đăng nhập vào lần tiếp theo.

Ngoài ra, giả sử bạn có chính sách theo đó người dùng phải đăng nhập ít nhất một lần trong 72 giờ. Trong trường hợp đó, logic làm mới mã thông báo API của bạn cũng sẽ kiểm tra ngày đăng nhập cuối cùng của người dùng từ cơ sở dữ liệu người dùng và từ chối / cho phép làm mới mã thông báo trên cơ sở đó.


7
Tôi không nghĩ rằng điều này sẽ an toàn. Nếu tôi là kẻ tấn công và đánh cắp mã thông báo của bạn và gửi nó đến máy chủ, máy chủ sẽ kiểm tra và xem cờ được đặt thành đúng, điều này thật tuyệt vì nó sẽ chặn làm mới. Vấn đề tôi nghĩ sẽ là nếu nạn nhân thay đổi mật khẩu, cờ sẽ được đặt thành false và bây giờ kẻ tấn công có thể sử dụng mã thông báo gốc đó để làm mới.
dùng2924127

6
@ user2924127 không có giải pháp xác thực nào là hoàn hảo và sẽ luôn có sự đánh đổi. Nếu kẻ tấn công đang ở trong một vị trí để 'đánh cắp mã thông báo của bạn', thì bạn có thể có vấn đề lớn hơn để lo lắng. Đặt tuổi thọ mã thông báo tối đa sẽ là một điều chỉnh hữu ích ở trên.
IanB

27
thay vì có một trường khác trong cơ sở dữ liệu, cờ reauth, bạn có thể đưa vào hàm băm (bcrypt_password_hash) trong mã thông báo. Sau đó, khi làm mới mã thông báo, bạn chỉ cần xác nhận nếu hàm băm (bcrypt_password_hash) bằng với một giá trị từ mã thông báo. Để từ chối làm mới mã thông báo, người ta phải cập nhật mật khẩu băm.
bas

4
@bas, nghĩ đến việc tối ưu hóa và hiệu suất, tôi nghĩ rằng xác thực băm mật khẩu sẽ là dư thừa và có nhiều ý nghĩa máy chủ hơn. Tăng kích thước của mã thông báo để công ty chữ ký / xác thực mất nhiều thời gian hơn. tính toán băm bổ sung cho máy chủ cho mật khẩu. với cách tiếp cận trường bổ sung, bạn chỉ cần xác nhận tính toán lại với một boolean đơn giản. Cập nhật Db ít thường xuyên hơn cho trường bổ sung, nhưng thường xuyên làm mới mã thông báo. Và bạn nhận được dịch vụ tùy chọn bắt buộc đăng nhập lại cho bất kỳ phiên hiện có nào (di động, web, v.v.).
le0diaz

6
Tôi nghĩ rằng nhận xét đầu tiên của user2924127 là thực sự sai. Khi mật khẩu được thay đổi, tài khoản được đánh dấu là yêu cầu xác thực lại, do đó, mọi mã thông báo đã hết hạn hiện tại sẽ không hợp lệ.
Ralph

15

Tôi đã mày mò xung quanh khi chuyển các ứng dụng của chúng tôi sang HTML5 bằng apis RESTful trong phần phụ trợ. Giải pháp mà tôi đã đưa ra là:

  1. Khách hàng được cấp mã thông báo với thời gian phiên là 30 phút (hoặc bất cứ thời gian phiên máy chủ thông thường nào) khi đăng nhập thành công.
  2. Một bộ đếm thời gian phía máy khách được tạo để gọi một dịch vụ để gia hạn mã thông báo trước khi hết hạn. Mã thông báo mới sẽ thay thế các cuộc gọi hiện tại trong tương lai.

Như bạn có thể thấy, điều này làm giảm các yêu cầu mã thông báo làm mới thường xuyên. Nếu người dùng đóng trình duyệt / ứng dụng trước khi cuộc gọi mã thông báo gia hạn được kích hoạt, mã thông báo trước đó sẽ hết hạn và người dùng sẽ phải đăng nhập lại.

Một chiến lược phức tạp hơn có thể được thực hiện để phục vụ cho người dùng không hoạt động (ví dụ: bỏ qua một tab trình duyệt đã mở). Trong trường hợp đó, cuộc gọi mã thông báo gia hạn phải bao gồm thời gian hết hạn dự kiến ​​không vượt quá thời gian phiên được xác định. Ứng dụng sẽ phải theo dõi tương tác người dùng cuối cùng cho phù hợp.

Tôi không thích ý tưởng thiết lập hết hạn lâu do đó phương pháp này có thể không hoạt động tốt với các ứng dụng gốc yêu cầu xác thực ít thường xuyên hơn.


1
Nếu máy tính bị treo / ngủ. Bộ đếm thời gian sẽ vẫn được tính cho đến khi hết hạn nhưng mã thông báo thực sự đã hết hạn. Đồng hồ bấm giờ không hoạt động trong tình huống này
Alex Parij

@AlexParij Bạn sẽ so sánh với một thời gian cố định, đại loại như thế này: stackoverflow.com/a353182296/1038456
Aparajita

2
Cho phép khách hàng yêu cầu mã thông báo mới có ngày hết hạn ưa thích có vẻ như là một rủi ro bảo mật đối với tôi.
java-nghiện602

14

Một giải pháp thay thế cho việc vô hiệu hóa JWT, không có bất kỳ lưu trữ an toàn bổ sung nào trên phụ trợ, là triển khai một jwt_versioncột số nguyên mới trên bảng người dùng. Nếu người dùng muốn đăng xuất hoặc hết hạn mã thông báo hiện tại, họ chỉ cần tăng jwt_versiontrường.

Khi tạo JWT mới, hãy mã hóa jwt_versionvào tải trọng JWT, tùy ý tăng giá trị trước nếu JWT mới sẽ thay thế tất cả các giá trị khác.

Khi xác thực JWT, jwt_versiontrường được so sánh cùng với user_idvà ủy quyền chỉ được cấp nếu phù hợp.


1
Điều này có vấn đề với nhiều thiết bị. Về cơ bản nếu bạn đăng xuất trên một thiết bị, nó sẽ đăng xuất ở mọi nơi. Đúng?
Sam Washburn

4
Này, đó có thể không phải là "vấn đề" tùy theo yêu cầu của bạn, nhưng bạn đã đúng; điều này không hỗ trợ quản lý phiên trên mỗi thiết bị.
Ollie Bennett

Điều này không có nghĩa là jwt_version phải được lưu trữ phía máy chủ sao cho sơ đồ xác thực trở thành "giống như phiên" và đánh bại mục đích cơ bản của JWT?
ChetPrickles

8

Câu hỏi hay - và có rất nhiều thông tin trong chính câu hỏi.

Bài viết Làm mới mã thông báo : Khi nào nên sử dụng chúng và cách chúng tương tác với JWTs đưa ra một ý tưởng hay cho kịch bản này. Một số điểm là: -

  • Làm mới mã thông báo mang thông tin cần thiết để nhận mã thông báo truy cập mới.
  • Làm mới mã thông báo cũng có thể hết hạn nhưng khá lâu.
  • Làm mới mã thông báo thường phải tuân theo các yêu cầu lưu trữ nghiêm ngặt để đảm bảo chúng không bị rò rỉ.
  • Họ cũng có thể được đưa vào danh sách đen bởi máy chủ ủy quyền.

Ngoài ra hãy xem auth0 / angular- jwt angularjs

Đối với API Web. đọc Kích hoạt mã thông báo làm mới OAuth trong ứng dụng AngularJS bằng API .NET .NET 2 và Owin


Có thể tôi đã đọc sai ... Nhưng bài viết có tiêu đề bắt đầu là "Làm mới mã thông báo ..." không chứa gì về mã thông báo làm mới, ngoại trừ những gì bạn đã đề cập ở đây.
Ievgen Martynov

8

Tôi thực sự đã triển khai điều này trong PHP bằng cách sử dụng máy khách Guheads để tạo thư viện máy khách cho api, nhưng khái niệm này sẽ hoạt động cho các nền tảng khác.

Về cơ bản, tôi phát hành hai mã thông báo, một ngắn (5 phút) và một mã dài hết hạn sau một tuần. Thư viện khách sử dụng phần mềm trung gian để thử làm mới mã thông báo ngắn nếu nhận được phản hồi 401 cho một số yêu cầu. Sau đó, nó sẽ thử lại yêu cầu ban đầu và nếu nó có thể làm mới nhận được phản hồi chính xác, minh bạch cho người dùng. Nếu thất bại, nó sẽ chỉ gửi 401 cho người dùng.

Nếu mã thông báo ngắn đã hết hạn nhưng vẫn xác thực và mã thông báo dài là hợp lệ và xác thực, nó sẽ làm mới mã thông báo ngắn bằng cách sử dụng điểm cuối đặc biệt trên dịch vụ mà mã thông báo dài xác thực (đây là điều duy nhất có thể được sử dụng). Sau đó, nó sẽ sử dụng mã thông báo ngắn để nhận mã thông báo dài mới, do đó sẽ kéo dài thêm một tuần nữa mỗi lần làm mới mã thông báo ngắn.

Cách tiếp cận này cũng cho phép chúng tôi thu hồi quyền truy cập trong vòng tối đa 5 phút, có thể chấp nhận cho việc sử dụng của chúng tôi mà không phải lưu trữ danh sách đen các mã thông báo.

Chỉnh sửa muộn: Đọc lại trong tháng này sau khi nó còn mới, tôi nên chỉ ra rằng bạn có thể thu hồi quyền truy cập khi làm mới mã thông báo ngắn vì nó tạo cơ hội cho các cuộc gọi đắt tiền hơn (ví dụ: gọi đến cơ sở dữ liệu để xem liệu người dùng có đã bị cấm) mà không trả tiền cho mỗi cuộc gọi đến dịch vụ của bạn.


8

Dưới đây là các bước để thu hồi mã thông báo truy cập JWT của bạn:

1) Khi bạn đăng nhập, hãy gửi 2 mã thông báo (Mã thông báo truy cập, Mã thông báo làm mới) để phản hồi cho khách hàng.
2) Mã thông báo truy cập sẽ có ít thời gian hết hạn hơn và Làm mới sẽ có thời gian hết hạn dài.
3) Máy khách (Giao diện người dùng) sẽ lưu trữ mã thông báo làm mới trong bộ nhớ cục bộ và mã thông báo truy cập trong cookie.
4) Khách hàng sẽ sử dụng mã thông báo truy cập để gọi apis. Nhưng khi nó hết hạn, hãy chọn mã thông báo làm mới từ bộ nhớ cục bộ và gọi api máy chủ auth để nhận mã thông báo mới.
5) Máy chủ xác thực của bạn sẽ có một api được hiển thị, nó sẽ chấp nhận mã thông báo làm mới và kiểm tra tính hợp lệ của nó và trả lại mã thông báo truy cập mới.
6) Khi mã thông báo làm mới hết hạn, Người dùng sẽ đăng xuất.

Vui lòng cho tôi biết nếu bạn cần thêm chi tiết, tôi cũng có thể chia sẻ mã (Java + Spring boot).


Bạn có thể vui lòng chia sẻ liên kết dự án của bạn nếu bạn có nó trong GitHub?
Arun Kumar N


6

jwt-autorefresh

Nếu bạn đang sử dụng nút (React / Redux / Universal JS), bạn có thể cài đặt npm i -S jwt-autorefresh.

Thư viện này lên lịch làm mới mã thông báo JWT tại số giây được người dùng tính toán trước khi mã thông báo truy cập hết hạn (dựa trên yêu cầu exp được mã hóa trong mã thông báo). Nó có một bộ kiểm tra mở rộng và kiểm tra khá nhiều điều kiện để đảm bảo mọi hoạt động lạ đều được kèm theo một thông báo mô tả liên quan đến cấu hình sai từ môi trường của bạn.

Thực hiện đầy đủ ví dụ

import autorefresh from 'jwt-autorefresh'

/** Events in your app that are triggered when your user becomes authorized or deauthorized. */
import { onAuthorize, onDeauthorize } from './events'

/** Your refresh token mechanism, returning a promise that resolves to the new access tokenFunction (library does not care about your method of persisting tokens) */
const refresh = () => {
  const init =  { method: 'POST'
                , headers: { 'Content-Type': `application/x-www-form-urlencoded` }
                , body: `refresh_token=${localStorage.refresh_token}&grant_type=refresh_token`
                }
  return fetch('/oauth/token', init)
    .then(res => res.json())
    .then(({ token_type, access_token, expires_in, refresh_token }) => {
      localStorage.access_token = access_token
      localStorage.refresh_token = refresh_token
      return access_token
    })
}

/** You supply a leadSeconds number or function that generates a number of seconds that the refresh should occur prior to the access token expiring */
const leadSeconds = () => {
  /** Generate random additional seconds (up to 30 in this case) to append to the lead time to ensure multiple clients dont schedule simultaneous refresh */
  const jitter = Math.floor(Math.random() * 30)

  /** Schedule autorefresh to occur 60 to 90 seconds prior to token expiration */
  return 60 + jitter
}

let start = autorefresh({ refresh, leadSeconds })
let cancel = () => {}
onAuthorize(access_token => {
  cancel()
  cancel = start(access_token)
})

onDeauthorize(() => cancel())

từ chối trách nhiệm: Tôi là người duy trì


Câu hỏi về điều này, tôi thấy chức năng giải mã nó sử dụng. Liệu nó giả định JWT có thể được giải mã mà không cần sử dụng bí mật? Nó có hoạt động với JWT đã được ký với một bí mật không?
Gian Franco Zabarino

3
Có, giải mã là giải mã chỉ dành cho khách hàng và không nên biết về bí mật. Bí mật được sử dụng để ký tên phía máy chủ mã thông báo JWT để xác minh rằng chữ ký của bạn đã được sử dụng để tạo JWT ban đầu và không bao giờ nên được sử dụng từ máy khách. Điều kỳ diệu của JWT là tải trọng của nó có thể được giải mã phía máy khách và các yêu cầu bên trong có thể được sử dụng để xây dựng giao diện người dùng của bạn mà không cần bí mật. Điều duy nhất jwt-autorefreshgiải mã nó là để trích xuất expyêu cầu để nó có thể xác định được bao xa để lên lịch làm mới tiếp theo.
cchamberlain

1
Thật tốt khi biết điều gì đó không có ý nghĩa nhưng bây giờ thì có. Cảm ơn câu trả lời.
Gian Franco Zabarino

4

Tôi đã giải quyết vấn đề này bằng cách thêm một biến trong dữ liệu mã thông báo:

softexp - I set this to 5 mins (300 seconds)

Tôi đặt expiresIntùy chọn theo thời gian mong muốn trước khi người dùng buộc phải đăng nhập lại. Của tôi được đặt thành 30 phút. Điều này phải lớn hơn giá trị của softexp.

Khi ứng dụng phía máy khách của tôi gửi yêu cầu đến API máy chủ (nơi yêu cầu mã thông báo, ví dụ: trang danh sách khách hàng), máy chủ sẽ kiểm tra xem mã thông báo đã gửi có còn hợp lệ hay không dựa trên expiresIngiá trị hết hạn ban đầu ( ). Nếu nó không hợp lệ, máy chủ sẽ phản hồi với trạng thái cụ thể cho lỗi này, vd. INVALID_TOKEN.

Nếu mã thông báo vẫn hợp lệ dựa trên expiredIngiá trị, nhưng nó đã vượt quá softexpgiá trị, máy chủ sẽ phản hồi với trạng thái riêng cho lỗi này, ví dụ: EXPIRED_TOKEN:

(Math.floor(Date.now() / 1000) > decoded.softexp)

Về phía khách hàng, nếu nhận được EXPIRED_TOKENphản hồi, nó sẽ tự động gia hạn mã thông báo bằng cách gửi yêu cầu gia hạn đến máy chủ. Điều này là minh bạch cho người dùng và tự động được chăm sóc ứng dụng khách.

Phương thức gia hạn trong máy chủ phải kiểm tra xem mã thông báo có còn hợp lệ không:

jwt.verify(token, secret, (err, decoded) => {})

Máy chủ sẽ từ chối gia hạn mã thông báo nếu không thành công phương pháp trên.


Chiến lược này có vẻ tốt. Nhưng tôi nghĩ nên được bổ sung bằng một loại "số lượng gia hạn tối đa" bởi vì (có thể) một người dùng sessión có thể tồn tại mãi mãi.
Juan Ignacio Barisich

1
Bạn có thể đặt biến hardExp trong dữ liệu mã thông báo để đặt ngày tối đa để hết hạn mã thông báo hoặc có thể là bộ đếm bị giảm bất cứ khi nào mã thông báo được gia hạn, giới hạn tổng số lần gia hạn mã thông báo.
James A

1
đúng rồi. Tôi coi đây là "phải".
Juan Ignacio Barisich

2

Cách tiếp cận này:

  • Đối với mọi yêu cầu của khách hàng, máy chủ sẽ so sánh thời gian hết hạn của mã thông báo với (currentTime - lastAccessTime)
  • Nếu expiredTime <(currentTime - lastAccessedTime) , nó sẽ thay đổi LastAccessedTime cuối cùng thành currentTime.
  • Trong trường hợp không hoạt động trên trình duyệt trong một khoảng thời gian vượt quá thời gian hết hạn hoặc trong trường hợp cửa sổ trình duyệt bị đóng và hết hạn> (currentTime - lastAccessedTime) , sau đó máy chủ có thể hết hạn mã thông báo và yêu cầu người dùng đăng nhập lại.

Chúng tôi không yêu cầu điểm cuối bổ sung để làm mới mã thông báo trong trường hợp này. Sẽ đánh giá cao bất kỳ feedack.


Đây có phải là một lựa chọn tốt trong ngày này không, nó có vẻ dễ thực hiện hơn nhiều.
b.ben

4
Trong trường hợp này, bạn lưu trữ LastAccessedTime ở đâu? Bạn phải làm điều đó vào phụ trợ và theo yêu cầu, vì vậy nó trở thành một giải pháp không mong muốn.
antgar9

2

Ngày nay, rất nhiều người lựa chọn để thực hiện quản lý phiên làm việc với JWTs mà không biết về những gì họ đang đưa lên vì lợi ích của nhận thức đơn giản. Câu trả lời của tôi giải thích ở phần 2 của câu hỏi:

Lợi ích thực sự sau đó là gì? Tại sao không chỉ có một mã thông báo (không phải JWT) và giữ hết hạn trên máy chủ?

Có những lựa chọn khác? Là sử dụng JWT không phù hợp cho kịch bản này?

JWT có khả năng hỗ trợ quản lý phiên cơ bản với một số hạn chế. Là các mã thông báo tự mô tả, chúng không yêu cầu bất kỳ trạng thái nào ở phía máy chủ. Điều này làm cho chúng hấp dẫn. Chẳng hạn, nếu dịch vụ không có lớp kiên trì, thì nó không cần phải mang một lớp chỉ để quản lý phiên.

Tuy nhiên, không quốc tịch cũng là nguyên nhân hàng đầu của những thiếu sót của họ. Vì chúng chỉ được phát hành một lần với nội dung cố định và hết hạn, bạn không thể làm những điều bạn muốn với một thiết lập quản lý phiên thông thường.

Cụ thể, bạn không thể làm mất hiệu lực chúng theo yêu cầu. Điều này có nghĩa là bạn không thể triển khai đăng xuất an toàn vì không có cách nào hết hạn mã thông báo đã phát hành. Bạn cũng không thể thực hiện thời gian chờ nhàn rỗi vì lý do tương tự. Một giải pháp là giữ một danh sách đen, nhưng điều đó giới thiệu trạng thái.

Tôi đã viết một bài giải thích những nhược điểm này chi tiết hơn. Để rõ ràng, bạn có thể giải quyết những vấn đề này bằng cách thêm độ phức tạp (phiên trượt, làm mới mã thông báo, v.v.)

Đối với các tùy chọn khác, nếu khách hàng của bạn chỉ tương tác với dịch vụ của bạn thông qua trình duyệt, tôi thực sự khuyên bạn nên sử dụng giải pháp quản lý phiên dựa trên cookie. Tôi cũng đã biên soạn một danh sách các phương thức xác thực hiện đang được sử dụng rộng rãi trên web.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.