2020年的愚人节,挺应景的,这段时间自己像是个愚人一样,哈哈。放平心态,该来的会来。
部门宣布执行全员日报制,每天汇报自己当天工作内容。
一个星期内的事情有点多,结束了之后收拾心情重新整装再出发。
不过不能放的东西就是不能放,所以继续推动blog编写吧。
此系列暂定分几篇,第一篇介绍jwt的相关知识,然后结合实际项目情况介绍shiro,让后结合它俩一起介绍一篇,然后结合spring cloud来写一篇我们项目中如何结合这些东西来在实际项目中使用的。
JWT
JWT: JSON.WEB.TOKEN
三个单词往这一放,应该也会猜到是为web的认证所使用的跟json有关的东西。
其官网为:https://jwt.io/
JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。
JWT构成
一个完整的JWT如下:1
2
3eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
eyJjb21wYW55SWQiOjAsImRlcGFydG1lbnRJZCI6MCwiZXhwIjoxNTg1NzEwMDc1LCJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4ifQ.
rEySOLc7l0WiogtcEOLBquzpa_5K6bgjrHpQjVbyEoo
为了显示方便我在其中两个点之后放了个换行。
从上面可以看出来一个完整的JWT包含如下三部分
- Header
- Payload
- Signature
第一部分:header
由两部分组成:token的类型(“JWT”)和算法名称(比如:HMAC SHA256或者RSA等等)1
2
3
4{
'alg': "HS256",
'typ': "JWT"
}
对这个json进行base64编码之后即可得到第一部分
第二部分:payload
这部分的数据是最灵活的,使用者可以往这部分的数据里面加任何想要的数据,但终归是你加的数据越多,这部分就约长,不能把完整的一个大对象都放在里面吧。
这部分数据(声明:claims)包含三种类型: registered, public 和 private。
Registered claims : 这里有一组预定义的声明,它们不是强制的,但是推荐。比如:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
Public claims : 可以随意定义。
Private claims : 用于在同意使用它们的各方之间共享信息,并且不是注册的或公开的声明。 下面是一个例子:
1 | { |
同样的,对payload进行Base64编码就得到JWT的第二部分
这里面不要放任何敏感信息,因为这部分其实是和第一部分是一样的,可以通过base64解码出来就是个明文了。暂可千万不能把用户的密码呀,身份证号啥的放在这里。
第三部分:signature
签名部分,这部分总结起来就是把第一部分加上第二部分经过特定算法进行签名,验证这个token是个合法的token。其中签名算法就是第一部分指定的签名算法。
例如:1
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
这里面有个secret 是要在咱们的应用程序里面保存好的,如果这个泄露了,其他人可以根据这个secret任意生成对于你来说合法的jwt了。
“对于你来说合法”的意思就是他可以伪造成一个合法的token了。好像有点绕口。
总结
以上其实就是JWT的内容了,是不是感觉有点扯?
是的,我也感觉有点扯,其实JWT真的就这么多内容,只不过是就上面的内容却可以在具体的场景中发挥作用。例如以下两点(后面文章我也会介绍到):
替代session
传统的session其实是保存在服务器端的,这无疑增加了服务器端的压力,成千上万的用户登录了平台之后服务器就得保存成千上万个session;
而token里面很重要的第一点是可以在payload里面保存信息的,这样就把用户的关键信息,例如用户编号放在这个JWT里面,当用户使用这个token进行某项操作时,服务端通过拿到这个token就可以拿到里面的用户编号,从而进行相应的操作。不需要保存session与用户的关系了。
服务器无状态。
上面说到session的时候其实也提到了服务器无状态的事,其实就是将传统的session与用户绑定的操作放在里客户端,服务端拿到token时只要验证其是一个合法的token,然后拿到payload里面的用户数据就可以找到对应的用户。
这对于尤其是移动端APP来说还是很方便的,移动端用户拿到一个token并保存在本地,服务器端不需要保存这个token的状态,由移动端自行维护,这样移动端APP在指定时间(例如两周?)内拿这个token进行请求都可正常请求,而不需要用户频繁的进行登录操作。
本篇就这么多吧,下面一篇来将shiro。