Json Web Token
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部分并未加密,所以不能把敏感信息放入其中。