前言
本文主要介绍基于token的身份认证方式以及介绍下JWT。
这是一个系列的,可以参考以下阅读顺序
正文
本文会首先介绍Web应用的身份认证,接着介绍基于token的身份认证并介绍常用的JWT。
身份认证
HTTP 是一种没有状态的协议。也就是说一个请求使用用户名还有密码通过了身份验证,下回这个网页再发送请求时候,还得再验证一下。
但在实际应用中我们需要一个机制去追踪状态,一个解决的方法就是传统的session-cookie解决方案。
基于token的身份认证
近年来RESTful API开始风靡,使用HTTP header来传递认证令牌似乎变得理所应当,而前后端分离架构似乎正在促成越来越多的WEB应用转而使用基于token的用户身份认证而不是传统的cookie+session。
一个基于token的身份认证机制主要是以下几步
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token,比如放在HTTP自定义头部里
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
这种方式的好处很多
- 无状态,毕竟token就只是个值,而且比如像JWT这种token上还可以带一些简单信息比如userId,就不像session的模式还要服务器端还要维护session,如果是分布式的还要解决session共享的问题。
- 多平台,多域名,如果是基于token的身份认证,可以把token附带在HTTP自定义头部来传递身份信息,这样我Android,IOS,WP都可以使用,一次开发,全平台适用的API服务器。而且cookie有域名限制,使用起来也一些限制。
JWT(json web token)
Json web token是一种产生token的标准,就我的理解这个应该是用得最多的。
一个JWT主要分三个部分
- header包含了两部分,一个是token的类型, 这部分最后是以base64编码的形式存放。 然后是指明用的哪个哈希算法加密的,比如HMAC SHA256。
- payload就是想要携带的信息,这部分最后也是以base64编码的形式存放
- signature是用来验证token是否合法的,也是token无法被伪造的关键。其生成的方法下图也有。

JWT的非对称加密
通常大家在使用JWT的时候都是使用HmacSHA256加密钥的加密方式,这种方式严格依赖密钥,在分布式开发的过程中,通常是由认证服务器生成JWT,然后再由资源服务器校验JWT的有效性,那么这时候资源服务器就也需要密钥了,认证服务和资源服务很可能是不同的团队开发和维护,密钥在这个过程中传递,很有可能泄漏。密钥一旦泄漏,对方就可以轻易的模拟一个JWTtoken出来,获取相关信息。
RSA非对称加密算法就可以很好的解决这个问题,认证服务器使用私钥生成JWT,资源服务器使用公钥去校验JWT,认证服务去管理私钥,公钥开放给各个资源服务,这样密钥泄漏的可能性就大大降低了。
后记(后期更新)
Refresh Token(待补充)
刚刚也讨论了下基于token的认证的优点,但这个方法是万能的么?
Stop using JWT for sessions, part 2: Why your solution doesn't work