前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >访问令牌过期后,如何自动续期?

访问令牌过期后,如何自动续期?

作者头像
Tinywan
发布2023-03-08 20:21:26
2.2K0
发布2023-03-08 20:21:26
举报
文章被收录于专栏:开源技术小栈开源技术小栈

介绍

JWT是JSON Web Token的缩写,是为了在网络应用环境间传递声明而执行的- -种基于JSON的开放标准((RFC 7519)。JWT本身没有定义任何技术实现,它只是定义了一种基于Token的会话管理的规则,涵盖Token需要包含的标准内容和Token的生成过程,特别适用于分布式站点的单点登录(SSO) 场景。

JWT Token格式如下所示:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

他是由.分割的三部分组成,这三部分依次是:

  • 头部(Header)
  • 负载(Payload)
  • 签名(Signature)

头部(Header)

JWT的Header中存储了所使用的加密算法和Token类型

Payload

Payload表示负载,也是一个JSON对象,JWT规定了7个官方字段供选用。

iss (issuer) : 签发人
exp (expiration time) : 过期时间
sub (subject) : 主题
aud (audience) : 受众
nbf (Not Before) : 生效时间
iat (Issued At) : 签发时间
jti (JWT ID) : 编号

除了官方字段,开发者也可以自己指定字段和内容。JWT默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这里。

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

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

Signature

Signature部分是对前两部分的签名,防止数据篡改。

首先,需要指定一一个密钥(secret) 。这个密钥只有服务器才知道,不能泄露给用户。然后,使用Header里面指定的签名算法(默认是HMAC SHA256),按照下面的公式产生签名。

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

认证&授权流程

  +-----------------------
  | RESOURCE EXISTS ? (if private it is often checked AFTER auth check)
  +-----------------------
    |       |
 NO |       v YES
    v      +-----------------------
   404     | IS LOGGED-IN ? (authenticated, aka has session or JWT cookie)
   or      +-----------------------
   401        |              |
   403     NO |              | YES
   3xx        v              v
              401            +-----------------------
       (404 no reveal)       | CAN ACCESS RESOURCE ? (permission, authorized, ...)
              or             +-----------------------
             redirect          |            |
             to login       NO |            | YES
                               |            |
                               v            v
                               403          OK 200, redirect, ...
                      (or 404: no reveal)
                      (or 404: resource does not exist if private)
                      (or 3xx: redirection)

Token过期的续期方案

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

单 Token方案

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

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

上面介绍的单token方案原理比较简单。下面再看一个双token方案。

双Token方案

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

微信网页授权是通过OAuth2.0机制实现的,也使用了双token方案

微信网页授权方案

  • 用户在第三方应用的网页上完成微信授权以后,第三方应用可以获得 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已经过期了。

实战环境

按照

composer require tinywan/jwt

生成令牌

$user = [
    'id'  => 2022, // 这里必须是一个全局抽象唯一id
    'name'  => 'Tinywan',
    'email' => 'Tinywan@163.com'
];
$token = Tinywan\Jwt\JwtToken::generateToken($user);
var_dump(json_encode($token));

输出(json格式)

{
    "token_type": "Bearer",
    "expires_in": 36000,
    "access_token": "eyJ0eXAiOiJAUR-Gqtnk9LUPO8IDrLK7tjCwQZ7CI...",
    "refresh_token": "eyJ0eXAiOiJIEGkKprvcccccQvsTJaOyNy8yweZc..."
}

签名算法

JWT 最常见的几种签名算法(JWA):HS256(HMAC-SHA256) 、RS256(RSA-SHA256) 还有 ES256(ECDSA-SHA256)

JWT 算法列表如下

+--------------+-------------------------------+--------------------+
| "alg" Param  | Digital Signature or MAC      | Implementation     |
| Value        | Algorithm                     | Requirements       |
+--------------+-------------------------------+--------------------+
| HS256        | HMAC using SHA-256            | Required           |
| HS384        | HMAC using SHA-384            | Optional           |
| HS512        | HMAC using SHA-512            | Optional           |
| RS256        | RSASSA-PKCS1-v1_5 using       | Recommended        |
|              | SHA-256                       |                    |
| RS384        | RSASSA-PKCS1-v1_5 using       | Optional           |
|              | SHA-384                       |                    |
| RS512        | RSASSA-PKCS1-v1_5 using       | Optional           |
|              | SHA-512                       |                    |
| ES256        | ECDSA using P-256 and SHA-256 | Recommended+       |
| ES384        | ECDSA using P-384 and SHA-384 | Optional           |
| ES512        | ECDSA using P-521 and SHA-512 | Optional           |
| PS256        | RSASSA-PSS using SHA-256 and  | Optional           |
|              | MGF1 with SHA-256             |                    |
| PS384        | RSASSA-PSS using SHA-384 and  | Optional           |
|              | MGF1 with SHA-384             |                    |
| PS512        | RSASSA-PSS using SHA-512 and  | Optional           |
|              | MGF1 with SHA-512             |                    |
| none         | No digital signature or MAC   | Optional           |
|              | performed                     |                    |
+--------------+-------------------------------+--------------------+

The use of "+" in the Implementation Requirements column indicates
that the requirement strength is likely to be increased in a future
version of the specification.

可以看到被标记为 Recommended 的只有 RS256ES256

对称加密算法

S256 使用同一个「secret_key」进行签名与验证。一旦 secret_key泄漏,就毫无安全性可言了。因此 HS256 只适合集中式认证,签名和验证都必须由可信方进行。

非对称加密算法

RS256 系列是使用 RSA 私钥进行签名,使用 RSA 公钥进行验证。

公钥即使泄漏也毫无影响,只要确保私钥安全就行。RS256 可以将验证委托给其他应用,只要将公钥给他们就行。

视频地址

  • 如何使用 JWT 认证插件:https://www.bilibili.com/video/BV1HS4y1F7Jx
  • 如何使用 JWT 认证插件(算法篇):https://www.bilibili.com/video/BV14L4y1g7sY
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源技术小栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 介绍
    • 头部(Header)
      • Payload
        • Signature
        • 认证&授权流程
        • Token过期的续期方案
          • 单 Token方案
            • 双Token方案
              • 微信网页授权方案
              • 实战环境
                • 按照
                  • 生成令牌
                  • 签名算法
                    • JWT 算法列表如下
                      • 对称加密算法
                        • 非对称加密算法
                        • 视频地址
                        相关产品与服务
                        云数据库 Redis
                        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档