今天上班,群里有朋友问介绍一个好用的AUTH认证第三方类。被人戏称面向框架编成。想想自己,为了成为一个好的架构师,怎么说也要手动实现一下吧
1、JWT 简述
JWT全称(JSON Web Token)是一种用于web开发中,用于身份验证的一种机制。这里也引用以下RFC7519的定义。
2、为什么使用JWT
我们来想象一下,普通开发流程中,出现用户身份认证,需要其登陆在能使用需求时,我们该如何实现呢?
实现这个需求首要条件就是判断来的这个请求到底是谁,但是http本身是无状态的,服务端无法判断这一次请求的人,是与上一次请求属于用一个端。而我们不可能在每次请求的时候都携带上用户的登陆账户与密码。其一是每次操作都需要验证是很没必要且浪费资源的,其二http安全性很低,用户信息容易被人恶意获取和使用。
此时引入了Session与Cookie的概念。当用户登陆后系统将用户登陆的信息存储在服务端(Session),抑或是客户端(Cookie)。
但这两种方式实现验证都不是太好,Cookies存在安全问题,是可以被伪造的。而Session则存在分布式集群同步问题,因为session只存在与用户登陆时认证的那台服务器里。如若时后期使用集群的话,那就还得考虑文件文件同步的问题。徒增没必要的io与资源消耗,还要使得架构变得无比复杂。
JWT就是为了解决这些难题而诞生的。它的工作流程就是用户登陆后,服务端根据用户登陆信息加上自己的密钥,生成一串TOKEN。用户拿到token后,在请求中携带这个token。服务端接受token判断这个token是否为我们颁发的。如果是,则验证成功。
3、JWT 功能实现
3.1 解构解析
以下就是jwt的构成要素,分别为Header,Payload,Sign
1 | graph TB |
引用JWT官网中的示例
1 | // Header 中包含加密算法约定,与token类型约定 |
token是将三个参数由”.”拼接,格式为 Header.Payload.Sign。之此jwt成功生成
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
token颁发,用户拿到后可以通过base64解密拿到前两个公开信息。请求时携带token,服务端通过判断Header.Payload加密后是否等于Sign。如果等于则为受信任token。因为token对外暴露的只有加密方式,加密信息,加密密钥只有服务器持有。所以如果不知道密钥,是无法成功伪造能被服务器认证的token。
这样就算服务器做分布式集群,只要保证服务器token验证密钥一样,用户的每一个访问就都能被成功识别。另外还可以payload中的信息,对用户请求做权限管理。
3.2 功能实现
上面了解了jwt的验证方式与构造,我们就可以开始自己手动实现一个简单的JWT验证功能。默认加密算法为HS256
1 |
|
此处代码为示例代码,有可能存在安全问题。请谨慎使用!
4、小结
web开发中JWT使用非常广泛,其传递方式有拼接在url上,也有放在http请求头中
1 | GET http://example.com/api HTTP/1.1 |
其内容扩展性也非常不错,比如可以在 payload 中加入用户等级,用户角色。这样后台可以在Middleware中就可以判断用户是否有权限访问该接口,达到系统解耦的效用。而且token是纯粹计算得出,不用以来其他有状态服务,如redis mysql等等。计算时没有IO操作,全在内存中完成,处理速度极快,非常适合高并发的场景。
当然,说了这么多有点,jwt也是有缺点的。即token一旦颁发,在有效期内绝对有效,无法收回。
所以为了安全考虑,架构师需要在系统架构师明确考虑好安全问题在使用。