基于JWT实现Token认证

JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案, 定义了一种紧凑自包含的,用于在多方传递JSON对象的技术。

在了解JWT之前,先了解一下目前两种主流身份验证方式:传统身份验证基于Token的身份验证

传统身份验证

HTTP 是一种无状态的协议,没有上下文会话机制,每一条HTTP请求都是相互独立的。为了识别用户和保存用户的状态,可以依靠Cookie和Session来处理,流程如下:

  1. 客户端使用用户名密码进行认证
  2. 服务端生成并存储 Session,将 SessionID 通过 Cookie 返回给客户端
  3. 客户端访问需要认证的接口时在 Cookie 中携带 SessionID
  4. 服务端通过 SessionID 查找 Session 并进行鉴权,返回给客户端需要的数据

jwt

这种身份验证方法,需要在服务端存储为登录的用户生成的Session,这些Session可能会存储在内存,磁盘,或者数据库里。

基于Token的身份验证

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

jwt

JWT

JWT的原则是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户。,当用户与服务器通信时,客户在请求中发回JSON对象。服务器仅依赖于这个JSON对象来标识用户。为了防止用户篡改数据,服务器将在生成对象时添加签名。 与基于Token的身份验证方法一样,服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。

jwt

Jwt 形式的 token 一般分为 3 个部分,分别是 Header,Payload,Signature,这三个部分使用 .分隔(格式:Header.Payload.Signature) 。其中前两部分使用Base64URL编码,未经加密处理,第三个部分使用 RSA 加密。

jwt

头部(HEADER)

HEADER主要为了描述该JWT的最基本信息,主要包含两个部分:声明类型和声明加密算法(通常直接使用HMAC,SHA256)

1
2
3
4
{
"alg": "HS256",
"typ": "JWT"
}

载荷(PAYLOAD)

载荷主要是存放有效信息,这些信息按照职能可以分成三个部分:

  • 标准的注册声明
  • 公共的声明
  • 私有的声明
1
2
3
4
5
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

标准的注册声明:

  • iss:jwt签发者
  • sub:jwt所面向的用户
  • aud:接收jwt的一方
  • exp:jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf:定义在什么时间之前,该jwt都是不可用的
  • iat:jwt的签发时间
  • jti:jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击

公共的声明

公共的声明可以添加任何的信息。一般这里我们会存放一下用户的基本信息(非敏感信息)

私有的声明

私有声明是提供者和消费者所共同定义的声明,不要存放敏感信息。

这些声明分类和字段,只是建议不强制使用。

签证(SIGNATURE)

JWT的第三部分是一个签证信息,这个签证信息主要由三个部分组成:Header(BASE64后),Payload(BASE64后),secret。

1
2
3
4
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

jwt

因为header和payload内容都是明文记录(base64编码,任何人获取到jwt之后都可以解码),除非记录的是加密数据,否则不排除泄露隐私数据的可能。不推荐在jwt中记录任何敏感数据。

jwt

JWT 默认是不加密,不加密的情况下,不要写入敏感数据 ,当然也可以在生成原始 Token 以后,用密钥再加密一次。

JWT使用方式

客户端接收服务器返回的JWT,将其存储在Cookie或localStorage中。此后,客户端将在与服务器交互中都会带JWT。如果将它存储在Cookie中,就可以自动发送,但是不会跨域,因此一般是将它放入HTTP请求的Header Authorization字段中。

1
Authorization: Bearer <token>

当跨域时,也可以将JWT被放置于POST请求的数据主体中。

有用就打赏一下作者吧!