本篇将包含以下内容:

  • 什么是JWT
  • JWT的组成
  • 如何使用JWT进行认证?
  • JWT的优缺点

什么是JWT?

JWT (Json Web Token) 是一种基于Token的认证授权机制。可以看到JWT本身就是一种Token。JWT是目前最流行的跨域解决方案。

Token本身携带信息,不需要想Session一样在服务器端保存session状态信息,而实现真正的无状态

JWT的组成?

JWT本身是一串字符串,但是其中包含了以下的信息:

  • Header
    • type: JWT
    • alg: signature使用 什么加密算法,比如HS256
  • Payload: 主要是一些data信息,也包括自身可以携带的比如签发者、签发日期、过期时间等等信息。
  • Signature:通过Header、Payload以及存在服务器上的secret,使用Header中的加密算法alg进行加密得到的签名。

Pre: Header + Payload

After: Base64(Header).Base64(Payload).HS256(Base64(Header).Base64(Payload), Secret)

我们可以看到Payload是使用Base64直接进行加密的,这意味着这一段很好破解,所以不要将隐私信息放在Token的Payload中。

JWT如何实现身份认证?

  1. 客户端从登录页面发送认证信息到服务器
  2. 服务器进行处理,认证成功后使用账户部分信息作为Payload以及服务器本身的secret生成JWToken,发送给客户端,服务器端不用存储任何信息
  3. 客户端最好将Token存储再localStorage中,这样可以防止CSRF(跨站请求伪造)攻击
  4. 客户端如果再对网站进行请求的时候,就会在Header中带有这个Token
  5. 服务端首先会根据Signature检查这个Token是否被篡改,然后会从这个Token中获得用户的信息。

那么JWT又是如何做到防止Token被篡改的呢?

​ 首先前面我们提到,JWT的Signature是需要服务器端的secrete以及Header和Payload同时进行加密的,一个黑客他可能会篡改Header或者是Payload中的信息,但是他不可能在没有Secret的情况对Signature进行篡改,所以最重要的是防止Secret泄露。服务器在接收到Token之后,他会根据其中的Header、Payload以及服务器的Secret同时进行生成一个Signature,与Token带的Signature进行比较。

JWT的优缺点

优点:

  1. JWT可以做到无状态,不在服务器存储东西
  2. 有效的避免CSRF(跨站请求伪造)攻击
  3. 单点登录友好

缺点:

  1. 不可控: 一旦我们登录成功之后,会获得一个带有有效期的Token,在有效期之内他是一直可用的,但是如果我们以及提出退出登录或者是其他的情况服务器端根本不知道,只知道他在有效期之内还会接收这个请求,也就是如果服务器端没有什么额外的逻辑的话,这个Token在失效之前是一直有效的。
    1. 退出登录
    2. 修改密码
    3. 服务端禁用了某个用户

解决方式:

  1. 存储在Redis中,一旦退出的话,直接将这个Token从其中删除掉,但是违背了无状态的原则
  2. 设置黑名单机制,如果手动失效的话,就让其加入到黑名单, 也违背了无状态的原则
  3. 修改密钥,每次改一个Token都要修改密钥,对于分布式系统来说不友好。
  4. 设置比较短的有效期,然后使用续签的机制。
  5. 返回两个accessToken 和 refreshToken,accessToken的有效期比较短,refreshToken的有效期比较长