登录认证与JWT
登录认证与JWT
目前主流的实现认证的方式有两种,Session和JWT
本文将着重于分析JWT
JWT的特点
无状态
JWT是无状态的,无状态性是指服务器端不需要存储任何关于用户会话或身份验证状态的信息。因此,服务器只需要验证JWT的签名和有效期来验证令牌的真实性和有效性,并据此授权用户的访问请求。
跨端 / 跨域支持
由于JWT的无状态性,使其非常适用于分布式系统和跨服务的身份验证场景。每个服务都可以独立地验证和解析JWT,无需进行共享或同步状态。同时由于不依赖Cookie等特性,在客户端中也可以使用JWT。
拓展性强
JWT的Payload部分可以添加任意所需信息,通过解密,服务端可以完整的拿到加密前的数据,可以包括用户的id
、username
等任意字段。
长度无限制
由于Payload部分可以添加任意JSON格式的数据,因此JWT的长度很可能会超过限制,导致溢出报错。
难以主动失效
正因为JWT的无状态性,想主动使其失效变得非常困难。通常JWT会设置过期时间exp
,但是有时我们需要主动令其失效,例如在用户修改了密码之后。一般的做法是设置黑名单,将失效的token信息维护在黑名单中,但是这与JWT的无状态性背驰,算是一个痛点。
JWT是什么
JWT全称为 Json Web Token, 其本质是多个JSON对象,用于在各方之间安全的传输信息。
JWT的构成
JWT由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
- 头部(Header):JWT的头部通常由两部分组成:令牌的类型(即JWT)和使用的签名算法,如HMAC、SHA256或RSA等。头部使用Base64编码进行序列化,但不加密,因此可以公开查看。
- 载荷(Payload):载荷是JWT的主要部分,用于携带实际的信息,例如用户的身份、权限等。载荷由一组称为声明(Claims)的键值对组成,可以包含预定义的标准声明(如iss、sub、exp等),也可以包含自定义的声明。与头部一样,载荷也使用Base64编码进行序列化,但不加密。
- 签名(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都是目前常用并且非常成熟的认证方式,各有优劣,具体选用那种认证方式,需要通过业务实际场景进行选择。
上一篇: 理解并简易实践JWT身份验证与授权机制
下一篇: JWT令牌认证是啥?简单解释一下
推荐阅读
-
利用 Spring Boot 与 Spring Security + JWT + MySQL 实现基于令牌的身份验证
-
机智云设备管理平台GDMS通过兼容适配认证实现与飞腾腾云S2500处理器的完美配合
-
设置SSL证书以实现HTTPS访问接口的单向与双向认证
-
一键登录:SSO与身份验证的完美结合
-
探索前端登录验证、页面跳转与 headers token 的实践与思考
-
两种实用方法与原理:在Linux系统中实现SSH RSA无密码登录
-
详述Ubuntu系统中ssh远程登录服务器的安装与配置步骤
-
在Windows和Linux之间进行SSH免密登录,包括Linux与Linux之间的互相登录
-
小白必看!解决Windows间OpenSSH ssh免密登录问题的方法与技巧
-
如何使用Xshell设置SSH无密码登录 - 公钥与私钥的配置方法