用户认证是计算机安全领域一个永恒的热点话题,然而你会发现,开发者很少讨论有关Json Web Token的话题,其实使用Json Web Token集成到API身份验证机制中是容易,本文给大家普及基础知识。

Json Web Token (简称JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519)。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,该token也可直接被用于认证,也可被加密。

传统的session认证

我们知道,http协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据http协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于session认证。传统的session认证方式对于单机单端应用非常方便。

但是这种基于session的认证使应用本身很难得到扩展,随着手机、电视等多种客户端(多端)的出现,独立的服务器已无法承载更多的用户,而这时候基于session认证应用的问题就会暴露出来。

session 缺点:

  • 数据以纯文本形式存储在服务器上
    即使数据通常不存储在公用文件夹中,但是任何具有访问权限的人都可以读取到session会话文件的内容。
  • 文件读写请求
    每次会话开始和数据被修改时,服务器都需要更新会话文件,这些文件读写都要消耗资源。每当应用程序发送会话cookie时也是如此。如果你的应用用户量比较大,将会导致服务器响应速度变慢,当然你也可以使用redis基于内存来存储session或者加大硬件配置,但随着认证用户的增多,服务端的开销会明显增大,这都不是最终解决办法。
  • 分布式应用
    由于session文件默认存储在文件系统中,因此对于多台服务器分布式负载均衡、集群方式架构的高可用应用就显得有点力不从心了,你可能要考虑session会话同步的问题了。

我们急需一种机制,每个请求中,可以在请求header头或者url中带上一串密钥,这个密钥就是通行证,而这个密钥的合法性和有效性有服务端来控制,那么我们的服务端只需鉴定这个密钥是不是授权的真实密钥,无需保存session文件信息,这个密钥就是token,翻译过来叫令牌

基于token的鉴权机制

基于token的鉴权机制类似于http协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于token认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

JSON Web Signature是一种加密机制,旨在保护具有对token内容唯一的数字签名的数据,以便我们能够确定token的数据是否已被篡改。

JWT的使用比单个API密钥有许多优点:

  • API密钥只是随机字符串,而JWT则包含可在一个时间范围或域内描述用户身份,授权数据和令牌有效性的信息和元数据
  • Oauth2兼容
  • JWT数据可以被检查
  • JWT有失效控制

流程上是这样的:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

这个token必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *

JWT结构

一个JWT应该像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE0MTY5MjkxMDksImp0aSI6ImFhN2Y4ZDBhOTVjIiwic2NvcGVzIjpbInJlcG8iLCJwdWJsaWNfcmVwbyJdfQ.XCEwpBGvOLma4TCoh36FU7XhUbcskygS81HE1uHLf0E

看起来,只是随机字符连接在一起的字符串,与API密钥没有太大的区别。 但是,如果仔细观察,你会发现实际上有3个字符串,以点号.字符分隔。

JWT由三部分构成。第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature)。

header

jwt的头部承载两部分信息:

  • 声明类型,这里是jwt
  • 声明加密的算法 通常直接使用 HMAC SHA256

完整的头部就像下面这样的JSON:

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

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

playload

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分:

  • 标准中注册的声明
  • 公共的声明
  • 私有的声明

标准中注册的声明 (建议但不强制使用) :

iss: jwt签发者

sub: jwt所面向的用户

aud: 接收jwt的一方

exp: jwt的过期时间,这个过期时间必须要大于签发时间

nbf: 定义在什么时间之前,该jwt都是不可用的.

iat: jwt的签发时间

jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

公共的声明 :

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密。

私有的声明 :

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

定义一个payload:

{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}

然后将其进行base64加密,得到Jwt的第二部分:

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

signature签名

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload); var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

将这三部分用.连接成一个完整的字符串,构成了最终的jwt:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

注意:secret是保存在服务器端的,jwt的签发生成也是在服务器端的,secret就是用来进行jwt的签发和jwt的验证,所以,它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。

有关JWT(Json Web Token)的那些事的更多相关文章

  1. 什么是JWT(Json Web Token)

    什么是 JWT (Json Web Token) 用户认证是计算机安全领域一个永恒的热点话题. JWT 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519). 该to ...

  2. Java JWT: JSON Web Token

    Java JWT: JSON Web Token for Java and Android JJWT aims to be the easiest to use and understand libr ...

  3. 如何在SpringBoot中集成JWT(JSON Web Token)鉴权

    这篇博客主要是简单介绍了一下什么是JWT,以及如何在Spring Boot项目中使用JWT(JSON Web Token). 1.关于JWT 1.1 什么是JWT 老生常谈的开头,我们要用这样一种工具 ...

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

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

  5. [更新]一份包含: 采用RSA JWT(Json Web Token, RSA加密)的OAUTH2.0,HTTP BASIC,本地数据库验证,Windows域验证,单点登录的Spring Security配置文件

    没有任何注释,表怪我(¬_¬) 更新: 2016.05.29: 将AuthorizationServer和ResourceServer分开配置 2016.05.29: Token获取采用Http Ba ...

  6. ( 转 ) 什么是 JWT -- JSON WEB TOKEN

    什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...

  7. 关于JWT(Json Web Token)的思考及使用心得

    什么是JWT? JWT(Json Web Token)是一个开放的数据交换验证标准rfc7519(php 后端实现JWT认证方法一般用来做轻量级的API鉴权.由于许多API接口设计是遵循无状态的(比如 ...

  8. API安全验证之JWT(JSON WEB TOKEN) OLCMS

    假如www.olcms.com/getUserInfo获取用户信息,你怎么知道当前用户是谁?有人说登陆时候我把他UID写入session了,如果是API接口,没有session怎么办,那么就需要把UI ...

  9. 5分钟搞懂:JWT(Json Web Token)

    https://www.qikegu.com/easy-understanding/892 JWT 基于token的用户认证原理:让用户输入账号和密码,认证通过后获得一个token(令牌),在toke ...

随机推荐

  1. html标签内部简单加js 一维数组求最大值 最小值两个值位置和数字金字塔图形

     html标签内部,简单加js <a href=""></a><!DOCTYPE html PUBLIC "-//W3C//DTD XHTM ...

  2. Leaflet-Leafletv0.7使用leaflet-bing-layer

    digidem/leaflet-bing-layer: Bing Maps Layer for Leaflet v1.0.0:从标题就可以看出要Leaflet v1.0.0才能用.其实leaflet ...

  3. 测开之路五十:monggodb安装与初步使用

    mongodb下载地址:https://www.mongodb.com/download-center Robo3T下载地址:https://robomongo.org/ 安装mongodb 双击无脑 ...

  4. delphi 在代码中 添加 TO-DO 并且 管理

    TO-DO List是一项非常好用的功能.采用她可以让我们很清楚的了解以前完成了那些任务,还有哪些任务需要做,由谁负责完成,是不是比较紧急的任务等.今天来不及完成的,明天上班就可以很快的找到任务所在的 ...

  5. spring boot 尚桂谷学习笔记04 ---Web开始

    ------web开发------ 1.创建spring boot 应用 选中我们需要的模块 2.spring boot 已经默认将这些场景配置好了 @EnableAutoConfiguration ...

  6. 斯坦福【概率与统计】课程笔记(二):从EDA开始

    探索性数据分析(Exploratory Data Analysis) 本节课程先从统计分析四步骤中的第二步:EDA开始. 课程定义了若干个术语,如果学习过机器学习的同学,应该很容易类比理解: popu ...

  7. CopyOnWriteArrayList(复制数组 去实现)

    一.Vector和SynchronizedList 1.1回顾线程安全的Vector和SynchronizedList 我们知道ArrayList是用于替代Vector的,Vector是线程安全的容器 ...

  8. css3中的scroll-behavior属性

    scroll-behavior属性 当用户手动导航或者 CSSOM scrolling API 触发滚动操作时,CSS 属性 scroll-behavior 为一个滚动框指定滚动行为,当用户通过鼠标滑 ...

  9. shell 脚本学习(一)

    一.vi编辑器的常用指令 1.命令行模式 x   #删除一个字符 dd #删除一整行 2.插入模式 i #在光标前插入内容 o   #在当前行之下新开一行 3.底行模式 x 或者 wq  #保存退出 ...

  10. 什么是restful风格?

    文章参考 RESTful API 设计指南--阮一峰 概念 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更 ...