本文目录
JWT可以取代以往的基于 COOKIE/SESSION 的鉴权体系,是目前最热门跨域鉴权的解决方案,接下来从 JWT 的原理,到 PHP 示例代码,简单说明业务怎样使用 JWT 进行授权验证。
JWT定制了一个标准,实际上就是将合法用户(一般指的是 通过 账号密码验证、短信验证,以及小程序code,或者通过其他验证逻辑 验证为合法的用户)的授权信息,加密起来,然后颁发给客户端。客户端请求需要鉴权的接口的时候,通过 HTTP报文 头部的 Authorization回传。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名:
下面是 JWT包含的数据:
Header(头部)
Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。
上面的JSON对象中,alg属性表示签名的算法,默认是 HMAC SHA256;typ属性表示这个令牌(token)的类型。
Payload(负载)
此部分主要用用于存放数据,其中有官方指定的默认字段,如下:
我们还可以添加自己的字段,但是不要我加密的信息放在这里,因为Paypload数据是谁都能解析出来的。我们一般把uid(用户id)、用户名等 开放信息存在这里
Signature(签名)
Signature是JWT最重要的部分,是对前两部分的签名,防止数据篡改。
基于JWT制定的标准,衍生出来了实现 JWT 的多个开源库 https://jwt.io/libraries ,当然我们也可以自己实现 JWT 的逻辑,但是也没有必要重复去造轮子,开发者应该利用更多的时间 去思考 有意义的事情。我们可以使用由 Google Firebase 开发的 firebase/php-jwt 库, 这个库也是目前最热门的 PHP JWT 库。下面介绍基于该库,实现常用的两种 JWT 验证方式。
HS256加密 :生成与验证JWT
使用 HS256 算法生成 JWT,这是一种对称加密,使用同一个密钥串进行加密和解密。
加密过程:
解密过程:
RS256加密 :生成与验证JWT
这是一种非对称加密,加密和解密使用 一个 密钥对
加密过程
解密过程
JWT 解密(验证)
如果正常通过验证,将解析出 payload 在加密前的原数据,我们可以基础处理业务逻辑;
如果 token 已经过期,或者 token 是非法 token,这时候我们通常认为用户的操作是 非法请求,系统也将会抛出对应的异常,我们只需进行捕获并 处理相关拦截的 逻辑即可。如下示例代码:
JWT 官网的标准是将 JWT 凭证放在 HTTP 报文 头部的 Authorization 中进行请求,如向服务器请求 用户的 个人信息,HTTP报文 如下示例
JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。
JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证(如通过手机 验证码 再次验证,或者再次输入用户密码进行验证)。