定义

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

适用场景

1、用于向Web应用传递一些非敏感信息。例如完成加好友、下订单的操作等等。

2、用于设计用户认证和授权系统。

3、实现Web应用的单点登录。

JWT的组成

一个JWT实际上就是一个字符串,它由三部分组成:头部载荷签名

实例场景

在A用户关注了B用户的时候,系统发邮件给B用户,并且附有一个链接“点此关注A用户”。链接的地址:https://your.awesome-app.com/make-friend/?from_user=B&target_user=A。

让B用户不用登录就可以完成这个操作。

载荷(Payload)

可以先将上面的添加好友的操作描述成一个JSON对象。并添加一些其他的信息,帮助收到这个JWT的服务器理解这个JWT。

{

"iss": "John Wu JWT",

"iat": 1441593502,

"exp": 1441594722,

"aud": "www.example.com",

"sub": "jrocket@example.com",

"from_user": "B",

"target_user": "A"

}

前五个字段都是由JWT的标准所定义的。

  • iss: 该JWT的签发者

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

将上面的JSON对象进行[base64编码]可以得到下面的字符串。这个字符串我们将它称作JWT的Payload(载荷)。

eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

如果你使用Node.js,可以用Node.js的包base64url来得到这个字符串。

var base64url = require('base64url')

var header = {

"from_user": "B",

"target_user": "A"

}

console.log(base64url(JSON.stringify(header)))

// 输出:eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9

小知识:Base64是一种编码,也就是说,它是可以被翻译回原来的样子来的。它并不是一种加密过程。

头部(Header)

头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象。

{

"typ": "JWT",

"alg": "HS256"

}

在这里,我们说明了这是一个JWT,并且我们所用的签名算法(后面会提到)是HS256算法。

对它也要进行Base64编码,之后的字符串就成了JWT的Header(头部)。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

签名(签名)

将上面的两个编码后的字符串都用点号连接在一起(头部在前),就形成了

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0

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

rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

这一部分又叫做签名

最后将这一部分签名也拼接在被签名的字符串后面,我们就得到了完整的JWT

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

于是,我们就可以将邮件中的URL改成

https://your.awesome-app.com/make-friend/?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcm9tX3VzZXIiOiJCIiwidGFyZ2V0X3VzZXIiOiJBIn0.rSWamyAYwuHCo7IFAgd1oRpSP7nzL7BF5t7ItqpKViM

这样就可以安全地完成添加好友的操作了!

八幅漫画理解使用JSON Web Token设计单点登录系统

用户认证八步走

所谓用户认证(Authentication),就是让用户登录,并且在接下来的一段时间内让用户访问网站时可以使用其账户,而不需要再次登录的机制。

小知识:可别把用户认证和用户授权(Authorization)搞混了。用户授权指的是规定并允许用户使用自己的权限,例如发布帖子、管理站点等。

首先,服务器应用(下面简称“应用”)让用户通过Web表单将自己的用户名和密码发送到服务器的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。

接下来,应用和数据库核对用户名和密码。

核对用户名和密码成功后,应用将用户的id(图中的user_id)作为JWT Payload的一个属性,将其与头部分别进行Base64编码拼接后签名,形成一个JWT。这里的JWT就是一个形同lll.zzz.xxx的字符串。

应用将JWT字符串作为该请求Cookie的一部分返回给用户。注意,在这里必须使用HttpOnly属性来防止Cookie被JavaScript读取,从而避免跨站脚本攻击(XSS攻击)

在Cookie失效或者被删除前,用户每次访问应用,应用都会接受到含有jwt的Cookie。从而应用就可以将JWT从请求中提取出来。

应用通过一系列任务检查JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。

应用在确认JWT有效之后,JWT进行Base64解码(可能在上一步中已经完成),然后在Payload中读取用户的id值,也就是user_id属性。这里用户的id为1025。

应用从数据库取到id为1025的用户的信息,加载到内存中,进行ORM之类的一系列底层逻辑初始化。

应用根据用户请求进行响应。


和Session方式存储id的差异

Session方式存储用户id的最大弊病在于要占用大量服务器内存,对于较大型应用而言可能还要保存许多的状态。一般而言,大型应用还需要借助一些KV数据库和一系列缓存机制来实现Session的存储。

而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如该用户是否是管理员、用户所在的分桶(见[《你所应该知道的A/B测试基础》一文](/2015/08/27/introduction-to-ab-testing/)等。

虽说JWT方式让服务器有一些计算压力(例如加密、编码和解码),但是这些压力相比磁盘I/O而言或许是半斤八两。具体是否采用,需要在不同场景下用数据说话。

单点登录

Session方式来存储用户id,一开始用户的Session只会存储在一台服务器上。对于有多个子域名的站点,每个子域名至少会对应一台不同的服务器,例如:

  • www.taobao.com

  • nv.taobao.com
  • nz.taobao.com
  • login.taobao.com

所以如果要实现在login.taobao.com登录后,在其他的子域名下依然可以取到Session,这要求我们在多台服务器上同步Session。

使用JWT的方式则没有这个问题的存在,因为用户的状态已经被传送到了客户端。因此,我们只需要将含有JWT的Cookie的domain设置为顶级域名即可,例如

1

Set-Cookie: jwt=lll.zzz.xxx; HttpOnly; max-age=980000; domain=.taobao.com

注意domain必须设置为一个点加顶级域名,即.taobao.com。这样,taobao.com和*.taobao.com就都可以接受到这个Cookie,并获取JWT了。

JSON Web Token的使用(转载)的更多相关文章

  1. JWT(JSON Web Token) 【转载】

    JWT(JSON Web Token) 什么叫JWTJSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. 一般来说,互联网用户认证是这样子的. 1.用户向服务器发送用户名和密码. ...

  2. JWT(Json Web Token):一种在Web应用中安全传递信息的规范 转载

    文本将介绍一种在Web应用中安全传递信息的方式,称为JWT. 本文内容是对JWT官网介绍说明的英文翻译而来,由于本文英文水平有限,如有错误,还请指出,谢谢. What is JSON Web Toke ...

  3. JWT(JSON Web Token) 多网站的单点登录,放弃session 转载https://www.cnblogs.com/lexiaofei/p/7409846.html

    多个网站之间的登录信息共享, 一种解决方案是基于cookie - session的登录认证方式,这种方式跨域比较复杂. 另一种替代方案是采用基于算法的认证方式, JWT(json web token) ...

  4. JSON Web Token - 在Web应用间安全地传递信息

    转载自:http://blog.leapoahead.com/2015/09/06/understanding-jwt/ JSON Web Token(JWT)是一个非常轻巧的规范.这个规范允许我们使 ...

  5. JSON Web Token入门教程

    目录 一.跨域认证的问题 二.JWT的原理 三.JWT的数据结构 3.1Header 3.2Payload 3.3 Signature 3.4 Base64URL 四.JWT的使用方式 五.JWT的几 ...

  6. 使用json web token

    由来 做了这么长时间的web开发,从JAVA EE中的jsf,spring,hibernate框架,到spring web MVC,到用php框架thinkPHP,到现在的nodejs,我自己的看法是 ...

  7. 理解JWT(Json Web Token)

    这篇文章写得不错: 理解JWT(JSON Web Token)认证及python实践,这里不做转载,仅摘要如下,有删改,仅做个人学习,感谢原作者. 常用认证机制: 1)HTTP basic Auth: ...

  8. 利用Redis撤销JSON Web Token产生的令牌

    利用Redis撤销JSON Web Token产生的令牌 作者:chszs.版权全部.未经允许,不得转载.博主主页:http://blog.csdn.net/chszs 早先的博文讨论了在Angula ...

  9. (转)深入浅出JWT(JSON Web token)

    转载地址:https://www.cnblogs.com/mantoudev/p/8994341.html 参考地址:https://baijiahao.baidu.com/s?id=16080218 ...

随机推荐

  1. java.lang.NoClassDefFoundError: Could not initialize class org.jfree.chart.JFreeChart

    最近在进行利用jfreechart生成图表时发现,项目在本地运行的好好的,一部署到服务器(linux系统)上就不行,报这样的错误: java.lang.NoClassDefFoundError: Co ...

  2. 374. Guess Number Higher or Lower 简单的二分法运用

    We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...

  3. springboot跨域请求

      首页 所有文章 资讯 Web 架构 基础技术 书籍 教程 Java小组 工具资源 SpringBoot | 番外:使用小技巧合集 2018/09/17 | 分类: 基础技术 | 0 条评论 | 标 ...

  4. hdu1227 dp

    题意:在一条路上有 n 个站点,并给定了每个站点的坐标,然后想要在 k 个站点旁边分别各建一个补给站,求所有站点到最近的补给站的距离和的最小值. 是的,毫无疑问,显然是 DP 问题,但是这题怎么递推还 ...

  5. 【HAOI2010】订货

    可以DP也可以是费用流,然而被我用非常简单的DP破了[开心] 原题: 某公司估计市场在第i个月对某产品的需求量为Ui,已知在第i月该产品的订货单价为di,上个月月底未销完的单位产品要付存贮费用m,假定 ...

  6. Math类的学习 java 类库 API 文档学习

  7. linux系统的启动过程及系统初始化

    (其中/etc/inittab是一个很重要的文件,值得细究http://www.2cto.com/os/201108/98426.html) 其开头的446字节内容特指为"主引导记录&quo ...

  8. hdu - 1823 - Luck and Love(线段树)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/SCNU_Jiechao/article/details/24406391 题意:Wiskey招女友, ...

  9. TweenMax.allTo

    需要多个MC进行相同的缓动.比如下面这个游戏菜单.三个按钮的缓动是相同的,都缓动到同一个x坐标位置.然后同时有缓动出舞台. 如果有TweenLite实现的话,需要             if (is ...

  10. Jmeter的CSV参数化策略

    前提:准备一份csv文件,数字为1-9即可 线程相当于vu,循环相当于迭代 一.所有线程所有线程共享这一份文件,数据有一个线程拿走了,其他线程就拿不走 例子1:只有1个线程,循环次数2次,那么,按照上 ...