跳到主要内容

JWT

传统的session认证

http协议无状态,浏览器和服务器之间,为了识别是哪个用户,需要在服务器端存储用户登录的信息,并通过cookie记录在浏览器,每次请求时,通过cookie来识别是哪个用户。

存在的问题

  1. 存储:用户经过认证,服务端要记录用户信息,以便下次请求的鉴别,随着用户增加,内存消耗增加

  2. 扩展:只在单机内存中记录,粘性session才能正确处理用户识别,分布式环境下,扩展能力受限。

  3. CSRF:基于cookie传递来识别身份,如果cookie被截取,很容易收到跨站请求伪造的攻击。

基于token的鉴权机制

类似于http协议,也是无状态的,不考虑在服务端保留用户的认证信息或者会话信息。不需要考虑用户在哪一台服务器登陆过,为扩展性提供了遍历。

基本流程:

用户使用用户名密码登录 => 服务器验证 => 验证通过发给用户一个token =>

客户端存储token并在每次请求时携带 => 服务端验证token有效性并返回数据

token一般保存在请求头里。

JWT

JSON Web Token - 在Web应用间安全地传递信息

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret');


var jwt_token = encodedString + '.' + signature

JWT由服务器签发和生成,并且有服务器来校验

校验的方式,是通过header和payload的内容,重新按规则计算jwt_token,比较用户传来的token和计算的token是否一致即可。

所以加密用的私钥secret就很重要,不能流露出去。否则谁都可以伪造生成合法的token了。

当验证token正确之后,就可以读取payload里的信息,确认用户身份真实且知道是哪个用户(payload里需要有用户信息),返回请求数据了。

优点

  • json格式,跨语言都可以很好的支持

  • payload里可以存储一些非敏感信息,可以携带一些额外信息

  • 传输压力小

  • 因为存在于客户端,服务端只做签发和校验,不用保存,服务端可以任意扩展

安全

  • payload是base64编码,可逆向解析,不应该存放敏感信息

  • 保护好secret

  • 使用https

理解

session存储在服务端,用户多会造成服务器存储资源消耗大,不论是用本地内存还是分布式缓存。

token存储在客户端,服务器只做验证处理,每次都要验证,会消耗服务器计算资源。

所以token是用时间换了空间的思路。

并且还有一个缺点,由于token发出后,就无法回收,所以无法做主动登出,只能等token过期。虽然可以通过减少过期时间,自动续期等方式来解决,但是无法实现实时主动登出。如果还在服务端记录token过期时间,相当于又回到了服务端存储的老路子了。