JWT是什么
一种加密过的字符串,给服务器做认证授权的,全名JSON Web Token
JWT的本质是加密
JWT的背景
一种工具的出现必然是为了解决某种痛点的,若生产过程无痛点,必然不会出现新工具
在JWT出现之前 服务器如何做授权登录
一种很简单的想法,必然是让服务器存一张表,用户登录的时候携带信息,服务器从表里面查询到是否存在该信息,若是存在,则授权客户端,不存在则登录失败
早期的鉴权就是这种方式-Session认证
Session认证
- 客户端向服务端发送消息,携带用户名,密码
- 服务端接收到消息,在表内存进信息。信息的key是sessionID , value是用户的详细信息
- 服务端给客户端返回一个cookie,cookie中包含sessionID
- 后续客户端访问服务端的请求中带着sessionID,服务端根据sessionID查询用户信息。
带来的问题
- 用户量达到百万,千万的级别,服务器将不堪重负
- 分布式系统中,数据不能同步,时效性带来大问题
- 移动端不能用,移动端无cookie
- 截获携带sessionID的cookie可以实现跨站请求伪造攻击
CSRF
思考痛点: 如何解决用户量大去查表这个最头疼的问题呢?
答案: 重新制定一种规则
JWT是如何做的?
大白话
将用户信息加密成一个字符串,后续只需要校验这个字符串解密后的信息即可,这个字符串解密后包含了所有服务端需要的信息
步骤
- 客户端第一次发送用户信息给服务端(账号、密码)
- 服务端查表校验信息真实性
- 信息真实,服务端使用JWT加密信息返回token字符串,可设置token有效期
- 客户端接收到该token,可以存下来(本地文件、LocalStore等)
- 客户端请求服务端,在cookie或者requestHead携带token
- 服务端拦截请求,拿到请求中的token字符串,使用JWT和密钥解密token
- 成功解密和token未过期,执行业务代码。否则返回错误信息
- token未过期之前,服务器不会去查表校验信息真实性,只需要解密拿到信息
Token安全吗?
世界上没有破解不了的系统,没有绝对安全的东西。
加密只是为了提高破解的难度,当时间沉没成本和收益不成正比,几乎不会有人去做
JWT生产的token采用对称加密和非对称加密技术,破解的难度非常大,而token中又会设置过期的时间,加密后的token是不一样的,又会进一步的增大破译难度
JWT的结构
- 标头: Header
- 有效载荷:Payload
- 签名:Signature
Header
存放头部数据,标识使用的加密算法和使用的令牌类型
{
"alg": "HS256", //加密算法
"typ": "JWT" //令牌类型
}
Payload
存放主体内容,传输的数据
//以下这些是预定义字段。可以进行自定义字段,内容只要符合json格式即可
{
"iss": "发行人",
"exp": "到期时间",
"sub": "主题",
"aud": "用户",
"nbf": "在此之前不可用",
"iat": "发布时间",
"jti": "JWT ID 用于标识此JWT",
}
Signature
一种签名标识,用以确保数据在网络传输中未经篡改。
Signature由加密算法和密钥生成,JWT的加密算法在网络中可以查询到。
密钥只存在服务端,服务端接收token会对签名进行校验。
//加密算法由 Header中的 alg 属性得知
Signature = function 加密算法( //两个参数 1、base格式的Header + . + base64格式Payload
base64enc(Header) // 2、密钥
+ '.'
+ base64enc(Payload),
密钥
)
JWT的种类
nonsecure JWT:无签名,无算法。不安全JWS:有签名,有算法,常用,安全JWE:Payload部分经过加密
拓展:JWT的签名算法
-
对称加密:
secretKey指加密密钥,可以生成签名与验签 -
非对称加密:
secretKey指私钥,只用来生成签名,不能用来验签(验签用的是公钥) -
HMAC【哈希消息验证码(对称)】:HS256/HS384/HS512
-
RSASSA【RSA签名算法(非对称)】(RS256/RS384/RS512)
-
ECDSA【椭圆曲线数据签名算法(非对称)】(ES256/ES384/ES512)