欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

登录认证与JWT

最编程 2024-07-28 11:56:44
...

登录认证与JWT

目前主流的实现认证的方式有两种,Session和JWT

本文将着重于分析JWT

JWT的特点

无状态

JWT是无状态的,无状态性是指服务器端不需要存储任何关于用户会话或身份验证状态的信息。因此,服务器只需要验证JWT的签名和有效期来验证令牌的真实性和有效性,并据此授权用户的访问请求。

跨端 / 跨域支持

由于JWT的无状态性,使其非常适用于分布式系统和跨服务的身份验证场景。每个服务都可以独立地验证和解析JWT,无需进行共享或同步状态。同时由于不依赖Cookie等特性,在客户端中也可以使用JWT。

拓展性强

JWT的Payload部分可以添加任意所需信息,通过解密,服务端可以完整的拿到加密前的数据,可以包括用户的idusername等任意字段。

长度无限制

由于Payload部分可以添加任意JSON格式的数据,因此JWT的长度很可能会超过限制,导致溢出报错。

难以主动失效

正因为JWT的无状态性,想主动使其失效变得非常困难。通常JWT会设置过期时间exp,但是有时我们需要主动令其失效,例如在用户修改了密码之后。一般的做法是设置黑名单,将失效的token信息维护在黑名单中,但是这与JWT的无状态性背驰,算是一个痛点。

JWT是什么

JWT全称为 Json Web Token, 其本质是多个JSON对象,用于在各方之间安全的传输信息。

JWT的构成

JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

  1. 头部(Header):JWT的头部通常由两部分组成:令牌的类型(即JWT)和使用的签名算法,如HMAC、SHA256或RSA等。头部使用Base64编码进行序列化,但不加密,因此可以公开查看。
  2. 载荷(Payload):载荷是JWT的主要部分,用于携带实际的信息,例如用户的身份、权限等。载荷由一组称为声明(Claims)的键值对组成,可以包含预定义的标准声明(如iss、sub、exp等),也可以包含自定义的声明。与头部一样,载荷也使用Base64编码进行序列化,但不加密。
  3. 签名(Signature):签名是JWT的第三部分,用于验证令牌的真实性和完整性。签名通常使用头部和载荷中的信息以及事先约定好的密钥来计算,以防止被篡改。签名是加密的,所以只有知道密钥的人才能验证令牌的有效性。

Header

Header通常包含两个信息,一个是加密算法,一个是类型。

{
  "alg": "HS256",  //加密算法
  "typ": "JWT"     //类型
}

Payload

Payload意为载荷,其实就是token中携带的信息。

官方默认给了7个字段,也可以自行添加

名称 含义
Audience 表示JWT的受众
ExpiresAt 失效时间
Id 签发编号
IssuedAt 签发时间
Issuer 签发人
NotBefore 生效时间
Subject 主题
{
  "loggedInAs": "admin",  //自定义内容
  "iat": 1422779638
}

Signature

Signature是签名,由前两个部分的内容通过一个事前约定好的密钥经过一定的加密算法计算而来。

HMAC_SHA256(
  secret,
  base64urlEncoding(header) + '.' +
  base64urlEncoding(payload)
)

JWT token

将三部分通过base64转码,并用.连接,就形成了key

const token = base64urlEncoding(header) + '.' + base64urlEncoding(payload) + '.' + base64urlEncoding(signature)

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI

JWT的失效

自动失效

一般来说,JWT在签发时会设置一个过期时间exp,并存储在token的Payload中。超过过期时间的token将无法认证。

主动失效

JWT的主动失效是无法直接实现的。通常会通过设置黑名单的方法,在服务器中维护一份黑名单,存储着需要失效的token的相关信息,例如id等。服务器在解密token后,会与黑名单中的数据进行比对,如果匹配则会认证失败。

刷新JWT

一般来说,在JWT自然失效后,为了用户的良好体验,会设置刷新token的功能。

通常服务器会在下发token时,额外下发一个刷新token(Refresh Token),当访问令牌(Access Token)过期后,客户端可以使用刷新令牌向服务器请求新的访问令牌,减少访问令牌的泄露风险。

通常访问令牌的过期时间较短,几十分钟至几小时不等,而刷新令牌的过期时间较长,几天乃至几十天。

后记

JWT和Session都是目前常用并且非常成熟的认证方式,各有优劣,具体选用那种认证方式,需要通过业务实际场景进行选择。