JWT(JSON网络令牌)到期自动延长JWT(JSON网络令牌)到期自动延长(JWT (JSON W

2019-05-10 09:53发布

我想实现基于JWT的验证我们新的REST API。 但由于到期的令牌设置,是可以自动延长吗? 我不希望用户需要的,如果他们积极利用这一时期的应用每隔X分钟后登录。 这将是一个巨大的失败UX。

但延长期满创建一个新的令牌(并直到它过期的旧的仍然有效)。 并且每个请求后生成新的令牌听起来很傻给我。 听起来像一个安全问题,当一个以上的标记是在同一时间有效。 当然,我可以使用无效黑名单旧广泛的一种,但我需要保存标记。 和智威汤逊的好处之一是没有存储。

我发现Auth0如何解决它。 他们不仅使用JWT令牌也刷新令牌: https://docs.auth0.com/refresh-token

但同样,为了实现这一点(不Auth0)我需要存储刷新令牌和维护他们的到期时间。 什么是真正的好处呢? 为什么不只有一个令牌(不JWT)和在服务器上保留期满?

是否有其他选择? 使用JWT不适合这种情况?

Answer 1:

我在Auth0工作,我参与了刷新令牌功能的设计。

这一切都取决于应用程序的类型,这里是我们推荐的方法。

Web应用程序

一个好的模式是其到期前刷新令牌。

令牌过期设置为一个星期,每次用户打开Web应用程序,并每隔一小时一次刷新令牌。 如果用户不打开一个多星期的应用程序,他们将不得不重新登录,这是可以接受的Web应用程序UX。

要刷新您的API需要接收一个有效的,未过期JWT,并与新的到期场返回相同的签署JWT新的端点的令牌。 然后,Web应用程序会在一些地方保存令牌。

移动/本机应用程序

大多数本地应用都登录一次,并且只有一次。

这个想法是刷新令牌永远不会过期,它总是一个有效的JWT进行交换。

使用永不过期令牌的问题是, 永远意味着永远。 什么,如果你失去了你的电话,你怎么办? 因此,它需要由用户可识别某种方式和应用程序需要提供一种方法来取消访问。 我们决定使用该设备的名称,如“maryo的iPad”。 然后,用户可以去申请,并撤销访问“maryo的iPad”。

另一种方法是撤销对特定事件的刷新令牌。 一个有趣的事件更改密码。

我们相信,智威汤逊是不是这些用例有用的,所以我们使用一个随机生成的字符串,我们将其存储在我们身边。



Answer 2:

在你自己处理身份验证(即不使用像Auth0提供商)的情况下,可以如下工作:

  1. 问题JWT令牌相对较短的到期,说15​​分钟。
  2. 应用程序检查需要令牌(令牌包含有效日期)的任何交易之前令牌到期日。 如果令牌已经过期,那么它首先要求的API“刷新”标记(此用户是透明的到UX)。
  3. API获取令牌刷新请求,但首先检查用户数据库,看是否有“重新验证”标志已经设置针对该用户的个人资料(令牌可以包含用户ID)。 如果标志存在,则该凭证更新被拒绝,否则新的令牌发放。
  4. 重复。

时,例如,用户重设密码数据库后端的“重新验证”标志将被设置。 该标志被去除当用户登录下一次。

另外,假设你有一个政策,规定用户必须每隔72小时登录至少一次。 在这种情况下,您的API凭证刷新逻辑还从用户数据库检查用户的最后一次登录的日期和拒绝/允许在此基础上令牌刷新。



Answer 3:

我们的移动应用程序时,HTML5与后端RESTful API中,我摆弄周围。 我想出了解决的办法是:

  1. 客户端用的30分钟(或任何一般的服务器端的会话时间)在成功登录会话时间令牌发出。
  2. 一个客户端的计时器创建调用服务的截止时间前续订令牌。 新令牌替换将来调用现有的。

正如你所看到的,这减少了频繁的刷新令牌请求。 如果用户触发更新令牌调用之前关闭了浏览器/应用程序,以前的令牌将在时间过期,用户必须重新登录。

越来越复杂的策略可以实施,以满足用户的活动(如忽略打开浏览器选项卡)。 在这种情况下,更新令牌调用应该包括预期的截止时间不得超过规定的会话时间。 该应用程序将跟踪最后一个用户交互的相应。

我不喜欢设定长期到期,因此这种方法可能不会需要那么频繁认证的本地应用程序很好地工作的想法。



Answer 4:

为无效JWTs,而不在后端任何额外的安全存储的备选解决方案,是实施新的jwt_version上用户表整数列。 如果用户想注销或者终止现有的令牌,他们简单地增加jwt_version领域。

当生成新的JWT,所述编码jwt_version入JWT有效载荷,任选预先递增值,如果新JWT应该更换所有其他人。

当确认了智威汤逊的jwt_version场旁边的比较user_id且仅当它匹配的授权是理所当然的。



Answer 5:

好question-并没有在这个问题本身的信息财富。

文章刷新令牌:何时使用他们,他们如何与JWTs交互给出了此方案是一个好主意。 有些点是: -

  • 刷新令牌进行必要得到一个新的访问令牌的信息。
  • 刷新令牌还可以到期,但相当长的寿命。
  • 刷新令牌,通常要经过严格的存储要求,以确保它们不被泄漏。
  • 它们也可以通过授权服务器列入黑名单。

也看一看auth0 /角JWT angularjs

对于Web API。 阅读使用ASP .NET的Web API 2启用AngularJS应用程序的OAuth刷新令牌,并Owin



Answer 6:

智威汤逊-自动刷新

如果您使用的节点(反应,和/终极版/通用JS),你可以安装npm i -S jwt-autorefresh

此库调度JWT的刷新在几秒钟内计算用户号码访问令牌到期(基于令牌编码的EXP权利要求)之前的令牌。 它具有广泛的测试套件,并检查了不少条件,以确保任何奇怪的活动是伴随着关于从您的环境配置是一个描述性的消息。

全面实施例

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())

免责声明:我是维护者



Answer 7:

我实际使用狂饮客户端,以便为API客户端库PHP实现这一点,但这个概念应该对其他平台上工作。

基本上,我发出了两个记号,​​短(5分钟),一个和一个漫长的一个星期后过期。 客户端库使用中间件,如果它接收到一个401响应于一些请求以尝试短令牌的一个刷新。 然后,它会再次尝试原始请求,如果它能够得到刷新正确的反应,以对用户透明。 如果它失败了,它将只发送401到用户。

如果短期令牌过期,但仍然真实,长令牌是有效的和真实的,它将使用上长令牌认证(这是它可以用于唯一)的服务特殊端点刷新短期令牌。 然后它会使用短令牌来获取新的长令牌,从而延长它一个星期每次刷新短期令牌时间。

这种方法还使我们能够在最多5分钟,这是我们可以接受的使用而不必存储令牌的黑名单内取消访问。

后期编辑:重读这个月它在我的头上新鲜后,我要指出的是,因为它给出了更昂贵的呼叫的机会,你可以刷新短令牌时撤销访问(例如调用数据库,看看用户已被取缔),而不在为你服务的每一个电话支付它。



Answer 8:

这个怎么样的方法:

  • 对于每一个客户机请求,该服务器比较与令牌的expirationTime(currentTime的 - 的LastAccessTime)
  • 如果expirationTime <(currentTime的- lastAccessedTime),它改变了过去lastAccessedTime到currentTime的。
  • 在浏览器上的一个持续时间超过expirationTime或者如果不活动的情况下,在浏览器窗口被关闭和expirationTime>(currentTime的- lastAccessedTime),然后服务器可以到期令牌并要求用户重新登录。

我们不要求额外的终点在这种情况下刷新令牌。 希望得到任何feedack。



Answer 9:

我在令牌数据添加变量解决了这个问题:

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

我设置expiresIn选项,我所希望的时间之前,用户将被迫重新登录。 矿设置为30分钟。 这必须是比的值大softexp

当我的客户端应用程序发送请求到服务器API(在需要的令牌,如:客户列表页),服务器会检查提交的令牌是否仍然有效或不基于其原始到期( expiresIn )值。 如果它是无效的,服务器会为这个错误特别是响应状态,例如。 INVALID_TOKEN

如果令牌仍然有效,基于expiredIn价值,但它已经超过了softexp值时,服务器将使用此错误的单独响应状态,例如。 EXPIRED_TOKEN

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

在客户端,如果它收到EXPIRED_TOKEN的响应,它会自动通过发送更新请求到服务器更新令牌。 这是透明的客户端应用程序的用户,并自动被照顾。

在服务器的更新方法必须检查令牌依然有效:

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

服务器将拒绝续约的令牌,如果它失败了上述方法。



Answer 10:

下面是做撤销你的智威汤逊访问令牌的步骤:

1)当你登录,以响应客户端发送2个令牌(访问令牌,令牌刷新)。
2)访问令牌将会有较少的到期时间,并刷新都会有较长的到期时间。
3)客户端(前端)将存储在他的饼干本地存储和访问令牌刷新令牌。
4)客户端将使用访问令牌调用的API。 但是到期时,拿起从本地存储刷新令牌和调用验证服务器API来获取新的令牌。
5)你的身份验证服务器将具有暴露的API将接受其有效性刷新令牌和检查,并返回一个新的访问令牌。
6)一旦刷新令牌过期,用户将被注销。

请让我知道如果你需要更多的细节,我可以共享代码(Java +春季启动),以及。



文章来源: JWT (JSON Web Token) automatic prolongation of expiration