关于token机制与JWT标准

在传统的web单体项目中,我们的会话通常使用session和cookie两样来实现。

传统的cookie/session实现

session是保存在服务器端的会话,使用cookie在客户端保存一个session id,每次发送请求的时候带上这个cookie服务端就可以很容易的了解当前用户是否与服务端建立了会话,以及会话是否过期等等。在单体项目中的这种实现机制相对来说是比较方便的。

使用这种机制存在的问题:

  1. 当我们的项目变得越来越大,用户数量越来越多之后,每新建一个会话服务器就要多消耗空间来存储空间,这将使服务器内存的开销不断增加;

  2. 跨域问题,很多项目使用前后端分离开发,而且前后端也部署在不同的域,这将导致一系列跨域问题的发生;

  3. 可拓展性,只在服务器内存中存储session限制了可拓展性能;

针对以上痛点,token机制的出现很好的解决了问题。

token机制

使用token机制时,当用户请求时,会检查用户是否有携带token信息,或者token是否过期;未登录的话叫用户进行登录,然后服务端生成一串token返回给浏览器,可以存储在cookie或者localStorage里面。以后用户每一次发送的请求都会带上这个token。

token的组成一般是一些基础的信息,加上一个签名。这样服务器就无需存储session,每当收到一个新的请求,对token的签名进行验证,验证成功就可以进行下一步的操作。而且通常token可以存储在数据库中。

JWT(Json Web Token)

广义上的jwt其实是token机制的一个实现标准,狭义上的jwt即是我们每次请求携带的token串。

jwt串由3部分组成,下面是一个例子:

1
2
3
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

第一部分为header为json格式

1
2
3
4
{    
"alg": "HS256", 加密算法类型
"typ": "JWT" token类型
}

第二部分为payload 同样为json:

1
2
3
4
5
{
"sub": "1234567890", 保留claim subject代表这个jwt的主体
"name": "John Doe", 自定义的claim
"iat": 1516239022 保留claim 时间戳 代表jwt的签发时间
}

第三部分就是用header中指定的算法结合payload的内容制造出的签名。

jwt串只是使用base64编码,并没有进行加密,所以任何人获取到jwt串都可以拿到其中传输的内容。

当服务端获取到这一tokne之后,会有如下事件流:

  1. 使用base64将jwt串进行还原

  2. 使用header中的算法对签名部分进行还原

  3. 对比直接从jwt中解析出的payload部分和使用算法还原的payload

    1. 如果不一致 验证失败

    2. 一致则验证成功

总结

token机制是针对无状态的http比较好的一个会话管理机制;对前后端分离项目、用户量大的项目都更加友好;对移动端的支持也更好。

参考资料:

https://jwt.io/

https://www.cnblogs.com/moyand/p/9047978.html

https://www.cnblogs.com/lyzg/p/6028341.html