Token 过期后,如何自动续期?


前言

    JWT(JSON Web Tokens)是一种开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在网络应用环境间安全地传输信息。这些信息通过数字签名的方式进行编码和验证,以确保信息的真实性和完整性。JWT可以在两个实体之间安全地传输信息,通常用于在用户和服务器之间传输认证和会话信息。


一、JWT 的组成

    JWT 通常由三部分组成,这三部分通过点(.)分隔,分别是:

1.Header(头部):头部包含了令牌的元数据,通常是两个字段:typ(类型,通常是JWT)和alg(签名使用的算法,如HMAC SHA256或RSA)。

{  
  "alg": "HS256",  
  "typ": "JWT"  
}

2.Payload(负载):负载包含了声明(claims)。声明是有关实体(通常是用户)和其他数据的声明。声明有三种类型:注册声明、公共声明和私有声明。

{  
  "sub": "1234567890",  
  "name": "John Doe",  
  "admin": true,  
  "iat": 1516239022  
}

这个JSON也被Base64Url编码形成JWT的第二部分。

3.Signature(签名):为了验证JWT的完整性和真实性,需要对其进行签名。签名是使用头部中指定的算法,对头部和负载的编码后的连接字符串进行签名。签名需要一个密钥(secret),只有持有这个密钥的实体才能验证签名的有效性。
签名过程大致如下:

HMACSHA256(  
  base64UrlEncode(header) + "." +  
  base64UrlEncode(payload),  
  secret)

签名也被Base64Url编码,形成JWT的第三部分。

二、JWT标准

    JWT token的 payload 部分是一个json串,是要传递数据的一组声明,这些声明被JWT标准称为claims。

JWT标准里面定义的标准claim包括:

  • iss(Issuser):JWT的签发主体;
  • sub(Subject):JWT的所有者;
  • aud(Audience):JWT的接收对象;
  • exp(Expiration time):JWT的过期时间;
  • nbf(Not Before):JWT的生效开始时间;
  • iat(Issued at):JWT的签发时间;
  • jti(JWT ID):是JWT的唯一标识。

    除了以上标准声明以外,我们还可以自定义声明。以 com.auth0 为例,下面代码片段实现了生成一个带有过期时间的token.

String token = JWT.create()
    .withIssuer(ISSUER)
    .withIssuedAt(new Date(currentTime))// 签发时间
    .withExpiresAt(new Date(currentTime + EXPIRES_IN * 1000 * 60))// 过期时间戳
    .withClaim("username", username)//自定义参数
    .sign(Algorithm.HMAC256(user.getPassword()));

其中:

  • withIssuer() 设置签发主体;
  • withIssuedAt() 设置签发时间;
  • withExpiresAt() 设置过期时间戳,过期的时长为 EXPIRES_IN (单位秒);
  • withClaim() 设置自定义参数。

    JWT设置了过期时间以后,一定超过,那么接口就不能访问了,需要用户重新登录获取token。如果经常需要用户重新登录,显然这种体验不是太好,因此很多应用会采用token过期后自动续期的方案,只有特定条件下才会让用户重新登录。

三、token过期的续期方案

    解决token过期的续期问题可以有很多种不同的方案,这里举一些比较有代表性的例子。首先我们看一个单token方案,这个方案除了可以实现token续期以外,还可以实现某些条件下的强制重新登录。

单token方案
在这里插入图片描述

  • 将 token 过期时间设置为15分钟;
  • 前端发起请求,后端验证 token 是否过期;如果过期,前端发起刷新token请求,后端为前端返回一个新的token;
  • 前端用新的token发起请求,请求成功;
  • 如果要实现每隔72小时,必须重新登录,后端需要记录每次用户的登录时间;用户每次请求时,检查用户最后一次登录日期,如超过72小时,则拒绝刷新token的请求,请求失败,跳转到登录页面。

    另外后端还可以记录刷新token的次数,比如最多刷新50次,如果达到50次,则不再允许刷新,需要用户重新授权。

双token方案

  • 登录成功以后,后端返回 access_token 和 refresh_token,客户端缓存此两种token;
  • 使用 access_token 请求接口资源,成功则调用成功;如果token超时,客户端携带 refresh_token 调用token刷新接口获取新的 access_token;
  • 后端接受刷新token的请求后,检查 refresh_token 是否过期。如果过期,拒绝刷新,客户端收到该状态后,跳转到登录页;如果未过期,生成新的 access_token 返回给客户端。
  • 客户端携带新的 access_token 重新调用上面的资源接口。
  • 客户端退出登录或修改密码后,注销旧的token,使 access_token 和 refresh_token 失效,同时清空客户端的 access_token 和 refresh_toke。

微信网页授权方案

  • 用户在第三方应用的网页上完成微信授权以后,第三方应用可以获得 code(授权码)。code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。
  • 第三方应用通过code获取网页授权凭证access_token和刷新凭证 refresh_token。
  • access_token是调用授权关系接口的调用凭证,由于access_token有效期(2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新。
  • refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。

    后端实现token过期还可以利用Redis来存储token,设置redis的键值对的过期时间。如果发现redis中不存在token的记录,说明token已经过期了。


总结

JWT 的优点

  • 无状态:JWT允许服务器无状态地验证用户的身份,因为JWT本身包含了所有必要的验证信息。
  • 易于使用:JWT易于在多种语言和平台之间传输,因为它只是一个JSON对象。
  • 安全性:JWT通过数字签名保证信息的真实性和完整性。

注意事项

  • 敏感信息:虽然JWT可以包含任何信息,但应避免在JWT中存储敏感信息,如密码。
  • 令牌过期:JWT可以设置过期时间(exp claim),以限制令牌的有效期。
  • 令牌刷新:为了安全起见,应定期更换JWT,并允许用户通过刷新令牌(refresh token)来获取新的JWT。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拥有必珍惜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值