JWT

1. 为何有JWT

服务器端维护登陆状态,使用传统Cookie和Session方案,扩展性很差。而JWT可实现服务器无状态,扩展性好。html

在单点登陆的时候,共享登陆状态信息的实现有如下两种方案:前端

  • 方案一:使用session 数据持久化(写入数据库或者Redis中),服务受到请求后,向持久层请求数据,但若是持久层挂了,就会单点失败。
  • 方案二:使用JWT,服务器不保存session数据,全部状态信息都保存在客户端,每次请求都发回服务器。

2. JWT是什么?

JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且独立的方式,用于在各方之间做为JSON对象安全地传输信息。 此信息能够经过数字签名进行验证和信任。 JWT可使用HMAC对称加密算法或RSA (ECDSA) 非对称加密算法进行签名。web

3. 实现原理?

服务器认证之后,生成一个json对象,发回给客户端。以后,客户端与服务端通讯,回传这个JSON对象。服务器靠这个对象认定用户身份。为防止用户篡改数据,服务器生成这个对象的时候,会加上签名。服务器再也不保存任何session数据,实现了服务无状态,从而比较容易实现扩展。算法

4. JWT长什么样?

Header.Payload.Signature数据库

  • Header:经Base64URL算法转成字符串的JSON对象,描述JWT的元数据,如签名算法(默认HMAC SHA256 对称加密)、令牌类型等属性
  • Payload:经Base64URL算法转成字符串的JSON对象,实际传输的数据,如签发人iss、主题sub、受众aud、过时时间exp、生效时间nbf、签发时间iat、编号jti (7个官方字段)以及自定义私有字段
  • Signature:对前两部分的签名,指定密钥secret ,对头部以及载荷内容进行签名。若是有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,即时使用相同密钥签名,结果也与原来的不同。若是不知道服务器加密时候用的秘钥的话,得出来的签名也是不同的。

截取自JWT官网

Base64URL算法json

Base64编码后的字符串中可能包含 + 、/ 和 = 三个字符,在 URL 里面有特殊含义,因此要被替换掉:= 被省略、+ 替换成-,/ 替换成 _ 。这就是 Base64URL 算法。api

JWT做为一个令牌(token),有些场景可能会放到URL(如:api.example.com/?token=xxx),所以须要采用Base64URL 算法将Header 和 Payload 转化为字符串。浏览器

5.存储位置?

JWT可选择的客户端存储位置包括sessionStorage、localStorage和cookie。三个位置各有优缺点,具体比较以下。安全

优势 缺点
sessionStorage 浏览器关闭即自动清除数据 存在不可跨浏览器窗口共享数据,跨窗口需从新登陆;可被JS读取,可能受到XSS攻击
localStorage 可跨窗口共享数据,过时时间前可实现自动登陆 退出登陆或JWT过时需主动清除数据;可被JS读取,可能受到XSS攻击
cookie 可设置httpOnly属性防止被JS读取,防止XSS攻击;可设置secure保证JWT只在HTTPS下传输 容易受到CSRF攻击

Token的初衷是防范CSRF攻击。防范大概的原理是,cookie会被浏览器自动带上,而token 或 JWT须要在发送请求前,前端代码中去设置请求头,防范了CSRF的攻击。XSS攻击的防范比较容易,所以笔者我的不推荐将JWT存在cookie里(我的意见,不喜勿碰)。服务器

6.JWT的优势和缺点

优势:

  • 全部状态信息存储在客户端,减轻了服务端压力
  • JWT不只能够用于认证,也能够用于交换信息。有效使用JWT,能够下降服务器查询数据库的次数

缺点:

  • 使用过程当中没法废止或修改,签发后到期前始终有效
  • 包含认证信息,泄露后权限被盗用 (针对该问题,建议采用较短的有效期,并使用HTTPS协议传输)
  • 续签问题

7.使用过程当中JWT失效怎么办?

若是在用户使用过程当中,JWT失效(过时时间到了),页面跳转至登陆页,这样会形成很差的用户体验。

  • 解决方案1:Refresh Token。服务器端token过时,通知客户端,客户端使用Refresh Token从新申请一个全新的JWT使用。
  • 解决方案2:将过时时间设置为深夜,好比凌晨三、4点,这样出现操做中token过时的可能性就极小了。该方案主要针对TO B业务。不过,即便是TO C的业务,凌晨三、4点使用的可能性也较小,真的碰上了登陆一下好像也能够理解。

关于Token

从范围来说,JWT属于Token,Token的形式能够多种多样,不限于JWT这种Header.Payload.Signature样子。JWT的特色大部分都适用于Token,固然Token也有本身的特性,本文(本次讨论)没有详细讨论Token相关内容,感兴趣的小伙伴能够自行发掘。

参考

https://JWT.io/introduction/

http://www.ruanyifeng.com/blo...

http://blog.didispace.com/jso...

相关文章
相关标签/搜索