第二十六节、1分钟学会SpringBoot2知识点,让你35岁不再失业(七)
第二十六节、springboot2整合JWT
1 、传统的session认证
传统session认证的方式:cookie和session结合使用
1.用户向服务器发送用户名和密码。
2.验证服务器后,用户信息将保存在session中。
3.服务器会把session_id写入到用户的Cookie。
4.用户后续每个请求都将通过在Cookie中取出session_id传给服务器。
5.服务器收到session_id并对比之前保存的数据,确认用户的身份。
这种模式最大的问题是,没有分布式架构,无法支持横向扩展。如果使用一个服务器,该模式完全没有问题。但是,如果它是服务器
集群部署的话,则需要一个统一的session数据库(一般使用redis来存储)来保存会话数据实现共享,这样负载均衡下的每个服务器才可
以正确的验证用户身份。
2、 基于token的鉴权机制
基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token
认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。
流程上是这样的:
用户使用用户名密码来请求服务器
服务器进行验证用户的信息
服务器通过验证发送给用户一个token
客户端存储token,并在每次请求时附送上这个token值
服务端验证token值,通过后放行处理具体业务。
3 、JWT 是什么
JWT 全称 JSON Web Tokens ,是一种规范化的 token。是对 token 这一技术提出一套规范。
4、JWT 结构
jwt有3个组成部分,每部分通过点号来分割 header.payload.signature
头部(header) 是一个 JSON 对象
负载(payload) 是一个 JSON 对象,用来存放实际需要传递的数据
签名(signature) 对header和payload使用密钥进行签名,防止数据篡改。
头部 header
Jwt的头部是一个JSON,然后使用Base64URL编码,承载两部分信息:
声明类型typ,表示这个令牌(token)的类型(type),JWT令牌统一写为JWT
声明加密的算法alg,通常直接使用HMACSHA256,就是HS256了,也可以使用RSA,支持很多算法(HS256、HS384、HS512、
RS256、RS384、RS512、ES256、ES384、ES512、PS256、PS384)
{
"alg": "HS256",
"typ": "JWT"
}
Base64URL 编码后(Base64编码后可能出现字符+和/,在URL中不能直接作为参数,Base64URL就是把字符+和/分别变成-和
_。JWT有可能放在url中,所以要用Base64URL编码。)
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
负载 payload
payload也是一个JSON字符串,是承载消息具体内容的地方,也需要使用Base64URL编码,就是存储我们要保存到客户端的信息,一
般都是包含用户的基本信息,权限信息,时间戳等信息。
JWT指定了一些官方字段(claims)备用:
iss: 签发人
exp: 过期时间
iat: 签发时间
nbf: 生效时间
jti: 编号
sub: 主题
aud: 受众
除了官方字段,在这个部分还可以添加私有字段,例如:
{
"sub": "fcf34b56-a7a2-4719-9236-867495e74c31",
"jwt-roles-key_": [
Base64URL编码的后:
签名 Signature
Signature部分是对前两部分的防篡改签名。将Header和Payload用Base64URL编码后,再用点(.)连接起来。然后使用签名算法和密钥
对这个字符串进行签名:
首先,需要指定一个密码(secret)。该密码保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法根据以下公式
生成签名。signature = HMACSHA256(header + "." + payload, secret); 在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部
分组合成一个字符串,每个部分用"."分隔,就构成整个JWT对象。 以上三部分都是在服务器定义,当用户登陆成功后,根据用户信
息,按照jwt规则生成token返回给客户端。
签名信息:
组合在一起
3部分组合在一起,构成了完整的jwt:
"超级管理员"
],
"iss": "yingxue.com",
"jwt-permissions-key": [
"sys:user:list",
"sys:dept:update",
"sys:dept:detail",
"sys:user:role:update",
"sys:permission:add",
"sys:user:add",
"sys:permission:update",
"sys:user:deleted",
"sys:user:detail",
"sys:dept:deleted",
"sys:role:update",
"sys:role:detail",
"sys:dept:list",
"sys:dept:add",
"sys:user:update",
"sys:role:list",
"sys:role:deleted",
"sys:permission:list",
"sys:permission:detail",
"sys:permission:deleted",
"sys:log:deleted",
"sys:user:role:detail",
"sys:role:add",
"sys:log:list"
],
"jwt-user-name-key": "admin",
"exp": 1584014849,
"iat": 1584007649
}
Base64URL编码的后:
eyJzdWIiOiJmY2YzNGI1Ni1hN2EyLTQ3MTktOTIzNi04Njc0OTVlNzRjMzEiLCJqd3Qtcm9sZXMta2V5XyI6WyLotoXnuqfnrqHnkIbl
kZgiXSwiaXNzIjoieWluZ3h1ZS5jb20iLCJqd3QtcGVybWlzc2lvbnMta2V5IjpbInN5czp1c2VyOmxpc3QiLCJzeXM6ZGVwdDp1cGRh
dGUiLCJzeXM6ZGVwdDpkZXRhaWwiLCJzeXM6dXNlcjpyb2xlOnVwZGF0ZSIsInN5czpwZXJtaXNzaW9uOmFkZCIsInN5czp1c2VyOmFk
ZCIsInN5czpwZXJtaXNzaW9uOnVwZGF0ZSIsInN5czp1c2VyOmRlbGV0ZWQiLCJzeXM6dXNlcjpkZXRhaWwiLCJzeXM6ZGVwdDpkZWxl
dGVkIiwic3lzOnJvbGU6dXBkYXRlIiwic3lzOnJvbGU6ZGV0YWlsIiwic3lzOmRlcHQ6bGlzdCIsInN5czpkZXB0OmFkZCIsInN5czp1
c2VyOnVwZGF0ZSIsInN5czpyb2xlOmxpc3QiLCJzeXM6cm9sZTpkZWxldGVkIiwic3lzOnBlcm1pc3Npb246bGlzdCIsInN5czpwZXJt
aXNzaW9uOmRldGFpbCIsInN5czpwZXJtaXNzaW9uOmRlbGV0ZWQiLCJzeXM6bG9nOmRlbGV0ZWQiLCJzeXM6dXNlcjpyb2xlOmRldGFp
bCIsInN5czpyb2xlOmFkZCIsInN5czpsb2c6bGlzdCJdLCJqd3QtdXNlci1uYW1lLWtleSI6ImFkbWluIiwiZXhwIjoxNTg0MDE0ODQ5
LCJpYXQiOjE1ODQwMDc2NDl9
签名 Signature
Signature部分是对前两部分的防篡改签名。将Header和Payload用Base64URL编码后,再用点(.)连接起来。然后使用签名算法和密钥
对这个字符串进行签名:
signature = HMACSHA256(header + "." + payload, secret);
首先,需要指定一个密码(secret)。该密码保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法根据以下公式
生成签名。signature = HMACSHA256(header + “.” + payload, secret); 在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部
分组合成一个字符串,每个部分用"."分隔,就构成整个JWT对象。 以上三部分都是在服务器定义,当用户登陆成功后,根据用户信
息,按照jwt规则生成token返回给客户端
签名信息:
KCL2-R5_OSsUw9S1-CZoCakO1OIPnwICH-tZozifoNM
组合在一起
3部分组合在一起,构成了完整的jwt:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJmY2YzNGI1Ni1hN2EyLTQ3MTktOTIzNi04Njc0OTVlNzRjMzEiLCJqd3Q
tcm9sZXMta2V5XyI6WyLotoXnuqfnrqHnkIblkZgiXSwiaXNzIjoieWluZ3h1ZS5jb20iLCJqd3QtcGVybWlzc2lvbnMta2V5IjpbInN
5czp1c2VyOmxpc3QiLCJzeXM6ZGVwdDp1cGRhdGUiLCJzeXM6ZGVwdDpkZXRhaWwiLCJzeXM6dXNlcjpyb2xlOnVwZGF0ZSIsInN5czp
wZXJtaXNzaW9uOmFkZCIsInN5czp1c2VyOmFkZCIsInN5czpwZXJtaXNzaW9uOnVwZGF0ZSIsInN5czp1c2VyOmRlbGV0ZWQiLCJzeXM
6dXNlcjpkZXRhaWwiLCJzeXM6ZGVwdDpkZWxldGVkIiwic3lzOnJvbGU6dXBkYXRlIiwic3lzOnJvbGU6ZGV0YWlsIiwic3lzOmRlcHQ
6bGlzdCIsInN5czpkZXB0OmFkZCIsInN5czp1c2VyOnVwZGF0ZSIsInN5czpyb2xlOmxpc3QiLCJzeXM6cm9sZTpkZWxldGVkIiwic3l
zOnBlcm1pc3Npb246bGlzdCIsInN5czpwZXJtaXNzaW9uOmRldGFpbCIsInN5czpwZXJtaXNzaW9uOmRlbGV0ZWQiLCJzeXM6bG9nOmR
lbGV0ZWQiLCJzeXM6dXNlcjpyb2xlOmRldGFpbCIsInN5czpyb2xlOmFkZCIsInN5czpsb2c6bGlzdCJdLCJqd3QtdXNlci1uYW1lLWt
leSI6ImFkbWluIiwiZXhwIjoxNTg0MDE0ODQ5LCJpYXQiOjE1ODQwMDc2NDl9.KCL2-R5_OSsUw9S1-CZoCakO1OIPnwICHtZozifoNM
5、使用要点
JWT默认是不加密的,但也可以加密,不加密时不宜在jwt中存放敏感信息
不要泄露签名密钥(secret)
jwt签发后无法撤回,有效期不宜太长
JWT 泄露会被人冒用身份,为防止盗用,JWT应尽量使用 https 协议传输
6、 JWT 怎么用
以浏览器接收到服务器发过来的jwt后,可以存储在Cookie 或 localStorage 中。之后,浏览器每次与服务器通信时都会带上JWT。可以将JWT放在Cookie中,会自动发送(不跨域),或将JWT放在HTTP请求头的授权字段中。
也可放在url中,或POST请求的数据体中
$.ajax({
url: "/api/user",
dataType: 'json',
type: 'GET',
beforeSend: function (request) {
request.setRequestHeader("authorization", "后端生成的token");
},
async: true,
cache: false,
success: function (res) {
}
});
7、springboot2封装jwt