2023-03-26
golang
00
请注意,本文编写于 668 天前,最后修改于 668 天前,其中某些信息可能已经过时。

目录

JWT介绍
JWT(JSON WEB TOKEN)
JWT由三部分组成
缺点:

JWT介绍

互联网服务离不开用户认证,一般流程如下!:

1.用户向服务器发送用户名和密码

2.服务器验证通过后,在当前对话(session)里面保存相关数据,比如用户角色、登录时间等

3.服务器向用户返回一个session_id,写入用户的 Cookie

4.用户随后的每一次请求,都会通过Cookie,将session_id传回服务器

5.服务器收到session_id,找到前期保存的数据,由此得知用户的身份

但使用这种方法,首先是扩展性不好,如果是单机服务那问题不大,如果是服务器集群的话,就需要实现session数据共享,使得每台服务器都能够读取session

这样的话就有一种解决方法是将session数据持久化,写入数据库或者别的持久层,各种服务收到请求后,都去向持久层请求得到数据,但是如果持久层挂掉了就会单点失败

另外一种就是将session由客户端进行保存,减少服务端的负载,每次请求都携带返回给服务器,JWT就是这种方法的一个方案

JWT(JSON WEB TOKEN)

一般在鉴权或者信息交换的过程中使用,主要是Authorization时使用,一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为开销很小

JWT由三部分组成
  • Header
  • Payload
  • Signature

一个jwt看起来就是xxxx.yyyy.zzzz

Header由两部分组成,token的类型("JWT")和算法名称比如(SHA256或RSA等等)

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

用base64对其进行编码就得到第一部分

Payload包含声明(要求),声明是关于实体(通常是用户)和其他数据的声明,声明有三种类型:registered,public和private

  • Registered claims

    是一些官方推荐的使用的字段,提供了一些有用的信息,iss(issuer):签发人
    exp(expiration time):注册时间 sub(subject):主题
    aud(audience):受众 nbf(Not Before):生效时间 iat(Issued At):签发时间
    jti(JWT ID):编号

  • Public claims

    在使用JWT时可以被自定义

  • Private claims

    用户自定义的一些信息

Signature(签名)

对第一部分和第二部分进行签名使用,用来验证是否是我们服务器发起的token,secert是我们的密钥
具体的签名过程则之后的文章再讲解,这里先跳过

那一个JWT验证的过程是怎么样的?

主要包括两个流程,一个是签名验证,另外一个是payload里面各个标准claim的验证

  • 签名验证

接收到一个JWT时,首先对完整性进行验证,防止被串改,因为签名是加入了私钥进行计算的,可以将签名段看为一个原始数据,然后对接收到的header解码,就能知道JWT用的是什么算法做的签名,然后再利用这个算法,对header和payload做一次签名,并比较两个签名是否完全相同,若相同则验证成功

  • payload验证

之后则对payload的claim验证

iss:如果签发时claim是'a.com',验证时不是的话则失败

sub:如果与签发时不同则验证失败

除了给定的registered claims验证以外,还需要开发者对自定义的claims进行验证

缺点:

即jwt不会注销,在过期时间之前它是始终有效的,比如用户点击了注销按钮,即结束了这个会话,客户端正常会清空它存储的token,但是实际上这个token在用户注销后还是有用的,还可以被攻击者窃取后进行使用,直到过期时间结束

那这时候就可以利用redis来撤销JWT产生的令牌,当用户点击注销后,且令牌在redis存储的时间与令牌在jwt的有效时间相同,当有效时间到了以后,令牌会自动被redis删除,然后每次先检验令牌在redis中是否存储,然后点击注销的时候也会发送请求注销令牌

本文作者:Malyue

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!