JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

目录

Token Auth机制

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

JWT通过用户发送用户名和密码给服务器,服务器验证通过之后,生成签名的token给客户端。客户端存储这个token,之后请求帐号相关的信息时带上token,服务端验证token之后,进行相应的处理。

相比cookie的优势

支持跨域站点访问

Cookie是不允许垮域访问的,可以通过设置顶级域名的方式实现部分跨域,但是跨站点的访问仍然不支持。

Token没有站点的限制,跨域站点的时候仍旧能够使用。

安全性更高

不需要考虑对CSRF(跨站请求伪造)的防范;

相比session的优势

节省服务器空间

session验证方式需要在服务端保存每个session,会占用服务器空间。如果单纯用DB存储,还有性能上的劣势;用redis等存储则不太经济。

Token方式将成本分摊到各个客户端,所需要的仅仅是一个解编码的过程。

JWT的组成

JWT由三部分组成,分别是头部、载荷和签名。三个部分中间用点分隔开,并且都使用 Base64 编码。

总体JWT示例:

eyJ0eXAiOiAiSldUIiwiYWxnIjogIkhTMjU2In0.eyJpc3MiOiAiaGFybGV5IiwiaWF0IjogMTUwMDk1NTk1MCwiZXhwIjogMTUwMDk1Nzk4NywidXNlcl9pZCI6ICI3ODk4IiwidXNlcl9yb2xlIjoiQWRtaW4ifQ.b0998815569be8f4ca8518030c3d586cc5bdff12dd7ad0004a1c38fa735ce18a

头部(Header)

header 部分主要包括两部分,一个是 Token 的类型,另一个是使用的算法, 比如Token类型是 JWT,使用的算法是 HS256。

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

经过base64编码之后的值为 eyJ0eXAiOiAiSldUIiwiYWxnIjogIkhTMjU2In0

有效载荷(payload)

有效载荷内部的数据可以自己定义,JWT规范也给出了一些标准字段,比如

  • iss: 该JWT的签发者
  • sub: 该JWT所面向的用户
  • aud: 接收该JWT的一方
  • exp(expires): 什么时候过期,这里是一个Unix时间戳
  • iat(issued at): 在什么时候签发的
  • jti(JWT ID): 唯一的JWT ID

比如payload内容如下:

{
    "iss": "harley",
    "iat": 1500955950,
    "exp": 1500957987,
    "user_id": "7898",
    "user_role": "Admin"
}

base64加密后的结果为

eyJpc3MiOiAiaGFybGV5IiwiaWF0IjogMTUwMDk1NTk1MCwiZXhwIjogMTUwMDk1Nzk4NywidXNlcl9pZCI6ICI3ODk4IiwidXNlcl9yb2xlIjoiQWRtaW4ifQ

签名(signature)

签名部分保证了token的安全性,signature的生成过程依赖前两部分的内容。 将Header和payload连接在一起,得到

eyJ0eXAiOiAiSldUIiwiYWxnIjogIkhTMjU2In0.eyJpc3MiOiAiaGFybGV5IiwiaWF0IjogMTUwMDk1NTk1MCwiZXhwIjogMTUwMDk1Nzk4NywidXNlcl9pZCI6ICI3ODk4IiwidXNlcl9yb2xlIjoiQWRtaW4ifQ

将上面拼接完的字符串用HS256算法进行加密。在加密的时候,还需要提供一个密钥。假设密钥为secret,那么就可以得到我们加密后的内容b0998815569be8f4ca8518030c3d586cc5bdff12dd7ad0004a1c38fa735ce18a

加在后面得到完成JWT

JWT安全性

JWT最后的签名部分对Header和payload进行了加密,如果Header和payload被篡改,最后的signature必然是不一样的。 由于加密时的secret是保密的,篡改者无法得到正确的签名。

但同时要注意的是,由于header和payload部分并未加密,所以不能把敏感信息放入其中。