目录:
一、JWT介绍
二、基于spring cloud + zuul + jwt 实战
三、源码地址
一、JWT介绍:
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
让我们来假想一下一个场景。在A用户关注了B用户的时候,系统发邮件给B用户,并且附有一个链接“点此关注A用户”。链接的地址可以是这样的
https://your.awesome-app.com/make-friend/?from_user=B&target_user=A
上面的URL主要通过URL来描述这个当然这样做有一个弊端,那就是要求用户B用户是一定要先登录的。可不可以简化这个流程,让B用户不用登录就可以完成这个操作。JWT就允许我们做到这点。
JWT的组成
一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。
JWT的适用场景
我们可以看到,JWT适合用于向Web应用传递一些非敏感信息。例如在上面提到的完成加好友的操作,还有诸如下订单的操作等等。
其实JWT还经常用于设计用户认证和授权系统,甚至实现Web应用的单点登录。
优点
因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。它不需要在服务端保存会话信息, 所以它易于应用的扩展缺点
一旦拿到token, 可用它访问服务器,直到过期,中间服务器无法控制它,如是它失效(有解决方案: 在 token 中保存信息,可添加额外的验证,如加一个 flag, 把数据库对应的flag失效,来控制token有效性)。
token的过期时间设置很关键,一般把它设到凌晨少人访问时失效,以免用户使用过程中失效而丢失数据。 - token保存的信息有限,且都是字符串。
安全相关不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。保护好secret私钥,该私钥非常重要。如果可以,请使用https协议有人提到jwt暴露签名算法(alg),而且会有None(无签名),所以建议隐去alg。
一般的协议制定都会考虑扩展性和普适性。但是我们在应用中可以采用我们默认的算法,而不是根据alg去处理。
二、基于spring cloud + zuul + jwt 实战
1、介绍:
本案例采用双token的方式完成jwt。其中accessToken 用于用户身份认证。refreshToken用于当accessToken失效时重新生成。
案例做了特别处理,当用户退出时,要主动将accessToken失效(redis维护),降低accessToken暴露的可能性。当accessToken做失效处理时,允许一定时间的容错时间(配置文件可设置),目的是避免并发访问时的异常。
2、实战源码
项目结构:
流程:
1、用户登录:
用户登录,zuul网关过滤器将访问跳转至认证微服务。在认证微服务验证用户名、密码,验证通过后生成accessToken 和refreshToken(注意:本案例使用用户密码当签名密钥,这样就避免了密钥集中泄密)。过期时间分别设置为1小时 和24小时(配置文件可修改这两个时间)。
返回两个token,在前端保存(本案例localStorage)如图:
2、token认证访问(accessToken有效):
当访问需要token认证的url时,zuul网关过滤器将请求转发至认证微服务,认证微服务通过accessToken验证是否合法。如果合法,zuul网关继续执行,访问其他微服务。
3、token认证访问(accessToken失效,refreshToken有效):
因为accessToken 的失效时间比refreshToken短,所以当accessToken失效时,refreshToken可能还未失效。因此前端主动发起二次请求,并将refreshToken发送到认证微服务,认证微服务验证refreshToken有效后,再次生成新的accessToken和refreshToken,并返回给前端,保存。
4、accessToken和refreshToken 都失效
当两个token都失效时,前端引导用户到登录界面,重新登录。
三、源码
https://github.com/wzjgn/zktd-bigdata-platform
閱讀更多 技術顧問聯盟 的文章