JWT简介

JSON Web Token(JWT)是一个开放式标准(RFC 7519),它定义了一种紧凑(Compact)且自包含(Self-contained)的方式,用于在各方之间以JSON对象安全传输信息。 这些信息可以通过数字签名进行验证和信任。 可以使用秘密(使用HMAC算法)或使用RSA的公钥/私钥对对JWT进行签名。

JWT结构

实施 Token 验证的方法挺多的,还有一些标准方法,比如 JWT,读作:jot ,表示:JSON Web Tokens 。JWT 标准的 Token 有三个部分:

  • header
  • payload
  • signature

中间用点分隔开,并且都会使用 Base64 编码,所以真正的 Token 看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

Header

header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 HS256。

1
2
3
4
5
{
  "typ""JWT",
 
  "alg""HS256"
}<br><br>

上面的内容要用 Base64 的形式编码一下,所以就变成这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:

iss:Issuer,发行者
sub:Subject,主题
aud:Audience,观众
exp:Expiration time,过期时间
nbf:Not before
iat:Issued at,发行时间
jti:JWT ID
比如下面这个 Payload ,用到了 iss 发行人,还有 exp 过期时间。另外还有两个自定义的字段,一个是 name ,还有一个是 admin 。

1
2
3
4
5
6
7
8
9
10
11
{
 
 "iss": "ninghao.net",
 
 "exp": "1438955445",
 
 "name": "wanghao",
 
 "admin": true
 
}

使用 Base64 编码以后就变成了这个样子:

eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ

Signature

JWT 的最后一部分是 Signature ,这部分内容有三个部分,先是用 Base64 编码的 header.payload ,再用加密算法加密一下,加密的时候要放进去一个 Secret ,这个相当于是一个密码,这个密码秘密地存储在服务端。

header
payload
secret

1
2
var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload); 
HMACSHA256(encodedString, 'secret');

处理完成以后看起来像这样:

SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

最后这个在服务端生成并且要发送给客户端的 Token 看起来像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

客户端收到这个 Token 以后把它存储下来,下回向服务端发送请求的时候就带着这个 Token 。服务端收到这个 Token ,然后进行验证,通过以后就会返回给客户端想要的资源。

JWT工作原理

在身份验证中,当用户使用他们的凭证成功登录时,JSON Web Token将被返回并且必须保存在本地(通常在本地存储中,但也可以使用Cookie),而不是在传统方法中创建会话 服务器并返回一个cookie。

关于存储令牌(Token)的方式,必须考虑安全因素。
参考: #Where to Store Tokens#

无论何时用户想要访问受保护的路由或资源,用户代理都应使用承载方案发送JWT,通常在请求头中的Authorization字段,使用Bearer schema:

Authorization: Bearer <token>

这是一种无状态身份验证机制,因为用户状态永远不会保存在服务器内存中。 服务器受保护的路由将在授权头中检查有效的JWT,如果存在,则允许用户访问受保护的资源。 由于JWT是独立的,所有必要的信息都在那里,减少了多次查询数据库的需求。

这使得我们可以完全依赖无状态的数据API,甚至向下游服务提出请求。 无论哪些域正在为API提供服务并不重要,因此不会出现跨域资源共享(CORS)的问题,因为它不使用Cookie。

Notice:

请注意,使用已签名的令牌,令牌中包含的所有信息都会暴露给用户或其他方,即使他们无法更改它。 在JWT中,不应该在Playload里面加入任何敏感的数据,比如像密码这样的内容。如果将用户的密码放在了JWT中,那么怀有恶意的第三方通过Base64解码就能很快地知道你的密码了。

参考:

【JWT】JWT+HA256加密 Token验证

深入浅出JWT(JSON Web Token )

最新文章

  1. Perst常用命令
  2. POJ 3274 HASH
  3. 如何提升 service 等级,不被kill(整合)
  4. [HIHO1079]离散化(线段树、染色)
  5. AngularJs自定义指令详解(1) - restrict
  6. ASP.NET Web API 路由
  7. 【Unity3D游戏开发】之Sprite Packer使用方法 (九)[转]
  8. 学习之spring属性文件注入
  9. 什么是MBeanServer
  10. php exit、return、break、continue之间的差别,具体介绍
  11. python_如何进行反向迭代和实现反向迭代?
  12. JS中数组和字符串的方法大全
  13. C语言实现循环队列
  14. ArcGIS Runtime For Android 100.3天地图不加载问题
  15. HDU--4486 Task(贪心)
  16. eclipse测试链接sql server2008 数据库
  17. numpy&amp;pandas笔记
  18. nginx: [error] invalid PID number &quot;&quot; in &quot;/var/run/nginx/nginx.pid&quot;
  19. HDU 3613 Best Reward(KMP算法求解一个串的前、后缀回文串标记数组)
  20. 使用百度webuploader实现大文件上传

热门文章

  1. Delphi ADOQuery多个参数重复 改编技巧
  2. 【数据库】MySQL 复制表结构
  3. Python中int()函数的用法浅析
  4. 迁移数据到历史表SQL(转)
  5. 【转】WinForms 使用Graphics绘制字体阴影
  6. 【刷题】HDU 4966 GGS-DDU
  7. 【目标检测大集合】R-FCN、SSD、YOLO2、faster-rcnn和labelImg实验笔记
  8. PID控制算法的C语言实现七&#160;梯形积分的PID控制算法C语言实现
  9. Python中scatter()函数--转载
  10. poj1816 Wild Words