JSON Web Token 使用详解
JWT 是什么?
JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案。它是有三部分组成,示例如下,具体的讲解如下(jwt 是不会有空行的,下面只是为了显示,便使用了换行看着比较方便)。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjMfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
它是由一个"."号隔开、三部分组成。
第一部分是 header 信息,
{
"alg": "HS256",// 加密的算法
"typ": "JWT"// 加密的方式,填写JWT
}
第二部分是 Payload,有固定的六个部分和自定义数据组成,自定义数据看自己的情况需要来定义,是可以省去的。
'iss' => 'https://www.qqdeveloper.com',// 签发人
'exp' => time() + 86400,// 过期时间(这里的有效期时间为1天)
'sub' => '主题内容',// 主题
'aud' => '受众内容',// 受众
'nbf' => $time,// 生效时间
'iat' => $time,// 签发时间
'jti' => 123,// 编号
第三部分是 Signature(是对前两部分加密得来的)。由于前两部分是公开透明的数据,因此防止数据的篡改和泄露,我们需要加密处理。首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
第一部分的加密方式(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
最终生成的就是上面很长的一段字符串了。
为什么会使用 JWT
这就需要从我们传统的认证模式来说了,传统的认证模式是基于 session 和 cookie 来实现用户的认证和鉴权。具体的流程模式如下图。

(图一)Session与Cookie认证与鉴权
1.客户端向服务端发送一个http请求。
2.服务端在收到客户端的请求时,生成一个唯一的 sessionid,这里需要将该生成的 session 存储在服务端,这个 sessionid 存储具体的 session 内容,默认的是文件存储,当然我们可以修改具体的存储方式,例如数据库存储。 3.客户端在接受到这个 sessionid 时,存在 cookie 里面,每次请求时携带该 sessionid。 4.服务端在接收到客户端的请求之后,根据客户端发送的 sessionid 来进行认证与授权。
这里也推荐一下自己之前分享的一篇有关 session 于 cookie 的知识点。session 与 cookie 详解
(图二)传统的token授权
1.客户端向服务端发送一个http请求。
2.服务端在收到客户端的请求之后,生成一个唯一 token,这里需要将该生成的 token 存储在服务端,至于怎么存,可以和上面 session 与 cookie 的方式一致。也可以存在缓存数据库中,如 redis,memcached。 3.服务端将该 token 返回给客户端,客户端存在本地,可以存请求头 header 中,也可以存在 cookie 中,同时也可以存在 localstorage 中。 4.向服务端发送请求时,携带该 token,服务端进行认证或者授权。

(图三)JWT认证模式
1.客户端向服务端发送一个http请求。
2.服务端根据 jwt 的生成规则,生成一个 token,并返回给客户端,这里服务端是不需要存储的。 3.客户端在接受到该 token 时,存在客户端。 4.客户端向服务端发送请求时,服务端对请求的 token 进行解析,如果发现解析出来的数据和生成的数据是一致的代表是一个合法的 token,则进行相应的操作。
基于 session 和 cookie 的认证和鉴权模式有什么好与不好的地方呢?总结如下几点:
通过上面几张图,我们也大致可以看得出来,基于 session 都是需要服务端存储的,而 JWT 是不需要服务端来存储的。针对以上几点,总结如下:
一、缺点 1.容易遇到跨域问题。不同域名下是无法通过 session 直接来做到认证和鉴权的。 2.分布式部署的系统,需要使用共享 session 机制 3.容易出现 csrf 问题。
二、优点 1.方便灵活,服务器端直接创建一个 sessionid,下发给客户端,客户端请求携带 sessionid 即可。
2.session 存储在服务端,更加安全。 3.便于服务端清除 session,让用户重新授权一次。
JWT 与 session 有什么区别呢?
JWT 是基于客户端存储的一种认证方式,然而 session 是基于服务端存储的一种认证方式。JWT 虽然不用服务端存储了,也可以避免跨域、csrf 等情况。但也存在如下几个不太好的地方。 1.无法清除认证 token。由于 JWT 生成的 token 都是存储在客户端的,不能有服务端去主动清除,只有直到失效时间到了才能清除。除非服务端的逻辑做了改变。 2.存储在客户端,相对服务端,安全性更低一些。当 JWT 生成的 token 被破解,我们不便于清除该 token。
如何使用 JWT
这里推荐使用 GitHub 上面人家封装好的包,这里我使用的是 firebase/php-jwt,在项目中直接使用即可安装成功。
composer require firebase/php-jwt
接下来创建一个控制器,我这里使用的 ThinkPHP5.1 的框架
use think\Controller;
use Firebase\JWT\JWT;
class Test extends Controller
{
private $key = 'jwtKey';
// 生成JWT
public function createJwt()
{
$time = time();
$key = $this->key;
$token = [
'iss' => 'https://www.qqdeveloper.com',// 签发人
'exp' => $time + 86400,// 过期时间(这里的有效期时间为1天)
'sub' => '主题内容',// 主题
'aud' => '受众内容',// 受众
'nbf' => $time,// 生效时间
'iat' => $time,// 签发时间
'jti' => 123,// 编号
// 额外自定义的数据
'data' => [
'userName' => '编程浪子走四方'
]];
// 调用生成加密方法('Payloadn内容','加密的键',['加密算法'],['加密的可以'],['JWT的header头'])
$jwt = JWT::encode($token, $key);
return json(['data' => $jwt]);
}
// 解析JWT
public function analysisJwt()
{
try {
$key = $this->key;
$jwt = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9leGFtcGxlLm9yZyIsImV4cCI6MTU2ODA5NjE4MCwic3ViIjoiXHU0ZTNiXHU5ODk4XHU1MTg1XHU1YmI5IiwiYXVkIjoiXHU1M2Q3XHU0ZjE3XHU1MTg1XHU1YmI5IiwibmJmIjoxNTY4MDA5NzgwLCJpYXQiOjE1NjgwMDk3ODAsImp0aSI6MTIzLCJkYXRhIjp7InVzZXJOYW1lIjoiXHU3ZjE2XHU3YTBiXHU2ZDZhXHU1YjUwXHU4ZDcwXHU1NmRiXHU2NWI5In19.kHb_9Np0zjE25YE9czUEGvmFPYtqMJT9tuZzJTuMZl0';
// 调用解密方法('JWT内容','解密的键,和加密时的加密键一直','加密算法')
$decoded = JWT::decode($jwt, $key, array('HS256'));
return json(['message' => $decoded]);
} catch (\Exception $exception) {
return json(['message' => $exception->getMessage()]);
}
}
}
通过访问第一个方法,可以生成下图一段字符串

我们将上图中的字符串复制到第二图中的$jwt 变量,访问第二个方法即可解析出具体的数据。

本文转自微信公众号 深夜有话聊 发布!
JSON Web Token 使用详解的更多相关文章
- Json Web Token(JWT)详解
什么是Json Web Token Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的 ...
- JWT(Json web token)认证详解
JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...
- JWT详解-(JSON Web Token教程)
JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法. 一.跨域认证的问题 互联网服务离不开用户认证.一般流程是下面这样. 1.用户向服务器发送用户名和密 ...
- Hacking JWT(JSON Web Token)
0x01 JWT工作流程 JSON Web Token(JWT)是一个非常轻巧的规范. 这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息. JWT常被用于前后端分离,可以和Restful ...
- Asp.net中web.config配置文件详解(一)
本文摘自Asp.net中web.config配置文件详解 web.config是一个XML文件,用来储存Asp.NET Web应用程序的配置信息,包括数据库连接字符.身份安全验证等,可以出现在Asp. ...
- Json Web Token(JWT)
Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(Si ...
- 《Tomcat与Java Web开发技术详解》思维导图
越想构建上层建筑,就越觉得底层基础很重要.补课系列. 书是良心书,就是太基础了,正适合补课. [纯文字版] Tomcat与Java Web开发技术详解 Servlet Servlet的生命周期 初始化 ...
- Web存储使用详解(本地存储、会话存储)
Web存储使用详解(本地存储.会话存储)1,Web存储介绍HTML5的Web存储功能是让网页在用户计算机上保存一些信息.Web存储又分为两种:(1)本地存储,对应 localStorage 对象.用于 ...
- 浅谈json web token及应用
Json Web Token (JWT),是一个非常轻巧的规范,这个规范允许在网络应用环境间客户端和服务器间较安全的传递信息.该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO) ...
随机推荐
- 渗透测试学习 二十一、 JSP相关漏洞
大纲 ST2漏洞 (Struts2) 反序列漏洞 网站容器,中间键 其他漏洞 Struts2漏洞 简介: Struts2是一个基于MVC设计模式的Web应用框架,它本质上相 ...
- 最长上升子序列(LIS: Longest Increasing Subsequence)
示例: 输入: [10,9,2,5,3,7,101,18] 输出: 4 解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4. 从网上找的一段代码(我由java改为了C++版本),原作者 ...
- 父组件调用子组件中的方法- this.$refs.xxx.子组件方法();
子组件中有一个说的方法 在父组件中去调用当你点击的时候 去调用子组件中的方法 fu.vue 在父组件的方法中调用子组件的方法,很重要 this.$refs.mychild.parentHandlecl ...
- gn-build
I'm not completely sure from the error you describe but it sounds like you don't have a .gn file in ...
- ACM-冒泡排序
将多组输入数据进行冒泡排序,并去除相同的数据 #include <iostream> #include <vector> using namespace std; void R ...
- 【第4题】 什么是https
https是基于http和SSL/TLS实现的一个协议,他可以保证在网络上传输的数据都是加密的,从而保证数据安全. 接下来我们从http协议开始,提出想法并逐步进行分析,最终实现Https. 1. h ...
- Django cache (缓存)
五种配置 1.开发调试 # 此为开始调试用,实际内部不做任何操作 # 配置: CACHES = { 'default': { 'BACKEND': 'django.core.cache.backend ...
- Paper | Residual Dense Network for Image Super-Resolution
目录 Residual dense block & network 和DenseNet的不同 摘要和结论 发表在2018年CVPR. 摘要和结论都在强调方法的优势.我们还是先从RDN的结构看起 ...
- OpenCV Error: Unknown error code -10 (Raw image encoder error: Empty JPEG image (DNL not supported)) in throwOnEror 错误
出现上面这样的错误可以肯定是传了空指针导致的, 刚开始出现这样的问题, 并且是概率性的, 网上找了一遍都没找到解决方案, 然后自己一行一行代码注释, 发现还是会出现这样的问题, 当时就懵逼了, 我从打 ...
- 剑指offer:序列化二叉(前序遍历+层次)
1. 题目描述 /** 请实现两个函数,分别用来序列化和反序列化二叉树 二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存. 序列 ...