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 使用详解的更多相关文章

  1. Json Web Token(JWT)详解

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

  2. JWT(Json web token)认证详解

    JWT(Json web token)认证详解 什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该to ...

  3. JWT详解-(JSON Web Token教程)

    JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理和用法. 一.跨域认证的问题 互联网服务离不开用户认证.一般流程是下面这样. 1.用户向服务器发送用户名和密 ...

  4. Hacking JWT(JSON Web Token)

    0x01 JWT工作流程 JSON Web Token(JWT)是一个非常轻巧的规范. 这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息. JWT常被用于前后端分离,可以和Restful ...

  5. Asp.net中web.config配置文件详解(一)

    本文摘自Asp.net中web.config配置文件详解 web.config是一个XML文件,用来储存Asp.NET Web应用程序的配置信息,包括数据库连接字符.身份安全验证等,可以出现在Asp. ...

  6. Json Web Token(JWT)

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

  7. 《Tomcat与Java Web开发技术详解》思维导图

    越想构建上层建筑,就越觉得底层基础很重要.补课系列. 书是良心书,就是太基础了,正适合补课. [纯文字版] Tomcat与Java Web开发技术详解 Servlet Servlet的生命周期 初始化 ...

  8. Web存储使用详解(本地存储、会话存储)

    Web存储使用详解(本地存储.会话存储)1,Web存储介绍HTML5的Web存储功能是让网页在用户计算机上保存一些信息.Web存储又分为两种:(1)本地存储,对应 localStorage 对象.用于 ...

  9. 浅谈json web token及应用

    Json Web Token (JWT),是一个非常轻巧的规范,这个规范允许在网络应用环境间客户端和服务器间较安全的传递信息.该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO) ...

随机推荐

  1. 实时SSH网络吞吐量测试

    centos 需要epel 源安装pv 软件,debian 需要安装pv 软件 #测试本机到192.168.1.158 的实时速率 yes | pv | ssh 192.168.1.158 " ...

  2. GitHub密钥生成

    前提电脑上需装有Git软件 这里提供百度云下载地址:https://pan.baidu.com/s/1r0y4XRyQCz7ZJBnZJhAtqw 提取码:88qf  1.登录GitHub账号 2.点 ...

  3. jQuery中的筛选(六)

    1. eq(index|-index) 获取当前链式操作中第N个jQuery对象,返回jQuery对象,当参数大于等于0时为正向选取,比如0代表第一个,1代表第二个.当参数为负数时为反向选取,比如-1 ...

  4. 【Spring JDBC】spring jdbc 介绍(一)

    Spring JDBC模块是Spring框架的基础模块之一.在Spring JDBC模块中,所有的类可以被分到四个单独的包: core 核心包:它包含了JDBC的核心功能.此包内有很多重要的类,包括: ...

  5. 第05组团队Github现场编程实战

    第05组团队Github现场编程实战 一.组员职责分工 组员 分工 卢欢(组长) 前后端接口设计 严喜 寻找相关资料 张火标 设计并描述界面原型 钟璐英 编写随笔 周华 填写完善文档 古力亚尔·艾山 ...

  6. 43 树莓派安装pytorch

    狗狗 https://www.pytorchtutorial.com/pytorch-c-api-4-cat-dog-classifier-2/ 鲜花分类器 https://www.pytorchtu ...

  7. Go micro 入门

    路由跳转 官方文档 本质上是选择不同的方式将HTTP信息合理的转发至后端处理,而不同的方式相当于不同请求的接收器,接收后再将其转发至不同的后端服务,完成整个请求的调用. micro 将请求选择不同的方 ...

  8. [LOJ 6433][PKUSC 2018]最大前缀和

    [LOJ 6433][PKUSC 2018]最大前缀和 题意 给定一个长度为 \(n\) 的序列, 求把这个序列随机打乱后的最大前缀和的期望乘以 \(n!\) 后对 \(998244353\) 取膜后 ...

  9. 数组去重--ES6方法

    数组去重方法1:用es6的set和...扩展运算符 let arr = [1,2,3,4,4,5,2]; console.log([...new Set(arr)]) // [1, 2, 3, 4, ...

  10. 'GL_EXT_shader_framebuffer_fetch' : extension is not supported

    在使用安卓模拟器加载Flutter应用时, 提示'GL_EXT_shader_framebuffer_fetch' : extension is not supported: D/skia (1404 ...