解读JWT算法及其应用

什么是JWT

Json Web Tokens 的简称,用来做跨域认证。在理解JWT前,我们先简单的看下常见的身份认证方式.

常见的身份认证方式

传统的,服务端存储session的方式难以做到不同服务间的身份校验。

  • 同域下
    同域可以通过session共享的方式达到多服务间的身份认证<相同服务不同节点或者不同服务间>。(通过将session集中存储共享),但是面临的问题是,当跨域情况下这个机制就行不通了。
  • 跨域情况下
    通常在一个组织内部可以使用sso的方式进行登录,但前提是每个服务器要实现sso的客户端,而且还必须要有浏览器的介入(相当于共享sso域下的cookie)。

上面两种方式的共同点是,用户session信息都存放在服务端.而JWT是一种将用户信息存放在客户端的方式.我们先看下最简单的使用JWT的场景.

JWT使用案例(场景再现)

  1. 小明打开系统登录页,填入用户名密码,发起登录请求.
  2. 后台服务收到登录请求后,验证用户名密码,通过后生成jwt返回给客户端.
  3. 客户端存储jwt,每次请求后台服务时带上jwt供后台使用.
  4. 后台服务每次收到请求后,校验jwt的合法性,并从中解析出用户信息,以供程序使用.

那JWT是怎么生成的?怎么携带用户信息?如何校验呢?

JWT算法

jwt算法通常用于无状态服务间用户身份传递,即将用户的信息存储在每次请求中,每次服务器通过解析token获取用户信息(服务器无状态)

首先我们会在每次请求中传递一个票据:token,通常的做法是在http header中存放一个:

Authentication: Bearer xxxxxtoken

Bearer: 来客 的意思,可以不加。

这个token里面包含了三个部分(组成):

 Header.Payload.Signature   (通过“.”连接)
  • Header 头部通常用来存放票据类型和所使用的签名算法:eg.
{
  typ: jwt
  alg: HS256
}

这里需要将Header使用Base64URL 算法转成字符串(需要注意一下不要使用Base64,因为在get请求过程中Base64编码后的部分字符会被浏览器改写,当然不用浏览器的话可以使用Base64)

  • Payload 存放了票据相关的信息: eg.
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
(根据实际情况自己选择使用)
--- 以上为官方字段,下面可以自定义自己的一些字段

username: zhangsan
age: 11

这里需要将Payload使用Base64URL 算法转成字符串

  • Signature 签名,使用头部指定的签名算法来校验请求是否合法:
Signature = HS256(Header + '.' + Payload, secret)

secret : 后台服务存放的统一的加密密钥

最终在头部传递的是:

Authentication: Bearer Header.Payload.Signature

对于分享性质的链接,可以考虑将token放到url中,但需要注意安全性.

服务端如何校验?

因为Header.Payload都是通过简单的Base64URL算法转换的,可以直接反序列化为明文,所以服务器接受到后可以直接从头部获取签名算法,然后使用服务器存储的secret进行签名计算,然后和传递过来的Signature进行比较是否相同确定合法性.

安全性

显然,header 和Payload是公开的,所有可以拦截这个请求的人都可以看到这里的内容,所以不适合传递敏感数据。可以通过使用https的方式增强安全性。


版权声明:本文为weixin_43002640原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。