一文了解JWT

2020-12-28  本文已影响0人  呆小鱼LQ

Our-task介绍

本篇博客是我github上our-task:一个完整的清单管理系统的配套教程文档,这是SpringBoot+Vue开发的前后端分离清单管理工具,仿滴答清单。目前已部署在阿里云ECS上,可进行在线预览,随意使用(附详细教程),大家感兴趣的话,欢迎给个star!

阿里云预览地址

一文了解JWT

介绍

JWT(Json Web Token)是目前最流行的跨域认证解决方案。它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

跨域认证的问题

传统认证流程

  1. 用户在浏览器输入用户名和密码提交,浏览器把用户名和密码发送到服务器。
  2. 服务器验证通过后,在当前会话(session)中保存相关数据,例如用户的名称、登录时间等等。
  3. 服务器向浏览器返回一个session_id,写入用户的cookie。
  4. 之后用户发起的每一次请求,都会通过cookie,将session_id传回服务器。
  5. 服务器收到session_id,找到之前保存的信息,从而得出用户的身份。

存在问题

在这种认证模式下存在的主要问题就是扩展性不好。单机肯定是没有问题的,但是如果存在多台服务器的集群的话,就要求session能够实现数据共享。

举例来说:我们有A、B、C三台服务器,用户在服务器A中进行登录,由于负载均衡的影响,该用户的下一次请求,可能会由服务器B处理,但是此时服务器B并没有存储用户登录的信息,于是用户又需要重新登录一次,这对用户来说当然是不能忍受的。

解决方案

  1. 一种方案是session数据持久化,把该session存储到数据库中,每个服务器在收到请求后,都需要向数据库请求数据。这种方案优点是架构清晰,缺点是工程比较大,毕竟每次都需要去请求数据库。
  2. JWT的方案就是:不让服务器保存session了,把所有的数据都保存在客户端,每次请求的时候,都把这些数据连同请求一起发送给服务器进行验证。

JWT详细介绍

无状态

由于服务器不保存任何session数据,从此服务器就变成无状态的了,从而容易实现扩展。

eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2MDc5MzMxMTcsInN1YiI6InVzZXIiLCJjcmVhdGVkIjoxNjA3OTI5NTE3ODQ4fQ.0VoICWN3FTCaFqtJ4q8zHk-K1jfWV-kJ8yRNYiWuvHcOX9kr8dKbHzPHIzG0WyvOmoNa0IN4B4QooX7hwZJraQ

JWT是一个很长的字符串,并且是没有换行的,另外,它由三部分组成,中间会有两个小点,类似:xxx.xxx.xxx这种形式。三个部分依次是:Header(头部)、Payload(负载)、Signature(签名)。

Header(头部)

Header部分是一个JSON对象,描述JWT的元数据,通常是下面的样子

{
    "alg":"HS256",
    "typ":"JWT"
}

上面的代码中,alg属性表明签名用的算法,默认是:HMAC SHA256,写为:HS256,typ属性表示这个令牌的类型,JWT令牌统一写为:JWT。

Payload(负载)

Payload部分也是一个JSON对象,用来存放实际需要传递的数据。JWT规定了7个官方字段:

  1. iss(issuer):签发人
  2. exp(expiration time):过期时间
  3. sub(subject):主题
  4. aud(audience):受众
  5. nbf(Not Before):生效时间
  6. iat(Issued At):签发时间
  7. jti(JWT ID):编号

除了官网字段,我们也可以自定义字段,比如:

  1. name:"xxx"
  2. age:18

不过需要注意的是,JWT默认是不加密这段的,任何人都可以读取到,所以不要把秘密的信息放在这里。

Signature(签名)

这部分是对前两部分的签名,防止数据篡改

首先,需要指定一个密钥,这个密钥只有服务器才知道,不能泄露给用户。

然后针对Header、Payload、Signature进行签名,把三个部分拼成字符串,每个部分点(.)分隔,返回给用户。

可以通过以下方式创建签名

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

JWT的使用方式

客户端收到服务器返回的JWT,可以存储在Cookie里面,也可以存储在localStorage里面。

之后,客户端每次请求服务器,都要带上JWT。可以把它放在Cookie里面自动发送,但是这样不能跨域。所以更好的做法是放在HTTP请求的头部信息Authorization字段里面。

另一种做法是,跨域的时候,JWT就放在POST请求的数据体里面。

上一篇下一篇

猜你喜欢

热点阅读