哈喽,大家好,我是指北君。 今天带大家来认识一下什么是jwt。
jwt简介
JWT(Json Web Token)是为了在网络应用环境间传递声明而执行的一种基于 Json 的开放标准。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。
基于token的鉴权机制
基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,由服务器通过秘钥(serectkey)然后把用户id以及其他信息包装进行一系列的加密算法生成,用户登录的成功,顺带把这个token返回到客户端,用户以后拿着token来访问相关资源,服务器接收到token,通过serectkey然后通过特定算法,解析出这个token中的用户id,解析成功!那么这个人就是该用户,然后通过解析出的id进行该用户的相关操作。这就为应用的扩展提供了便利。
JWT的认证流程如下:
- 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口,这个过程一般是一个POST请求
- 后端核对用户名和密码成功后,将包含用户信息的数据作为JWT的Payload,将其与JWT Header分别进行Base64编码拼接后签名,形成一个JWT Token,形成的JWT Token就是一个如同{header}.{payload}.{signature}的字符串后端将JWT Token字符串作为登录成功的结果返回给前端。前端可以将返回的结果保存在浏览器中,退出登录时删除保存的JWT Token即可.
- 前端在每次请求时将JWT Token放入HTTP请求头中,后端检查前端传过来的JWT Token,验证其有效性,比如检查签名是否正确、是否过期、token的接收方是否是自己等等
- 验证通过后,后端解析出JWT Token中包含的用户信息,进行其他逻辑操作(一般是根据用户信息得到权限等),返回结果
注:这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin:
JWT的构成
1 |
|
第一部分我们称它为头部(header),第二部分我们称其为载荷(payload,类似于飞机上承载的物品),第三部分是签证(signature)。
头部(header)
jwt的头部承载两部分信息:
- 声明类型,这里是jwt
- 声明加密的算法,通常直接使用 HMAC SHA256。这的加密算法也就是签名算法。
{ “alg”:”HS256” } 经过Base64编码之后 ewogICAgImFsZyI6IkhTMjU2Igp9
载荷(payload)
载荷就是存放有效信息的地方。这些有效信息包含三个部分
- 标准中注册的声明
- 公共的声明
- 私有的声明
1
2
3
4
5
6{ "sub":{"userId":"9527","userName":"test9527"}, "exp":1656561468, "iat":1656559668, "jti":"test9527" }
- sub: 主体,一般是用户信息,最好不要放入敏感信息
- exp: jwt的过期时间,这个过期时间必须要大于签发时间
- iat: jwt的签发时间
- jti: jwt的唯一身份标识
签证(signature)
这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。 signature顾名思义就是签名,签名一般就是用一些算法生成一个能够认证身份的字符串,secret配置在服务器端,不能泄露出去,就可以自己给自己签发token了。
JWT的使用(JAVA)
创建一个新项目,引入jwt包
1 |
|
JWT工具类:
1 |
|
- 创建controller类
- 访问测试
- 拿到的token可以使用Base64解码,可以看到,能看到用户信息,所以,token中不要带有敏感信息,防止泄露。
- 使用该token调用getUser接口,可以正确解析
- 下面我们不使用getToken获取token,而是伪造一个token,
1
2
3
4
5
6
7
8
9{ "sub":{ "userId":"001", "userName":"test001" }, "exp":1656561468, "iat":1656559668, "jti":"test001" }
- 再组合header,payload和signature,得到新的token访问getUser
1
eyJhbGciOiJIUzI1NiJ9.ewogICAgInN1YiI6ewogICAgICAgICJ1c2VySWQiOiIwMDEiLAogICAgICAgICJ1c2VyTmFtZSI6InRlc3QwMDEiCiAgICB9LAogICAgImV4cCI6MTY1NjU2MTQ2OCwKICAgICJpYXQiOjE2NTY1NTk2NjgsCiAgICAianRpIjoidGVzdDAwMSIKfQ==.7oot0glDxaL-g7pOJ2mZld2VLRhpo0h5y_BbVI4ZolA
- 得到结果如下:无法正确解析token,说明此token无效 最后, JWT过期时间要设置适宜 ,过长,可能会被截取到,造成用户信息泄露安全等问题;过短用户体验不佳。