JWT验证
理解 JSON Web Token(JWT) 验证
JSON Web Token认证的操作指南
在本文中,我们将了解JSON Web Token的全部内容。
我们将从JWT的基本概念开始,然后查看其结构,最后创建一个简单的服务器,它将获取一些数据并将其插入到JWT中。
什么是JSON Web Token?为什么我们需要它?
JSON Web Token(JWT)是一种安全,紧凑且独立的方式,以JSON对象的形式在多方之间传输信息。
假设你想登录一个应用程序,比如说 Tinder。 Tinder允许用户使用他们的Facebook个人资料登录。 因此,当用户选择使用Facebook登录的选项时,该应用程序会使用用户的凭据(用户名和密码)联系Facebook的身份验证服务器。
验证服务器验证用户的凭据后,将创建JWT并将其发送给用户。 该应用程序现在获得此JWT并允许用户访问其数据。
jwt的结构
一个jwt是由三个以"."来区分开的部分来组成的,他们是:
- 头部
- 负载
- 签名
标头通常由两部分组成:令牌的类型和正在使用的散列算法。
{
"alg": "HS256",
"typ": "JWT"
}
负载是我们要发送的实际信息的存储位置。 以下是简单有效负载的示例。 要知道负载可能比这个示例更复杂,以确保更好的安全性。
{
"sub": "65165751325",
"name": "Rajat S",
"admin": true
}
签名用于验证消息在到达目的地之前没有被更改。 这通常通过使用私钥来实现。
这三个部分通常编码为三个在他们之间由.分隔的Base64-URI字符串
要轻松解码,验证,生成或只是使用JWT,请查看Auth0的JWT.IO调试器。
现在我们已经基本了解了JSON是什么,让我们来看看如何构建一个简单的身份验证服务器来发布JWT,然后我们将使用它来访问API。
提示:在JavaScript中编写可重用代码时,可以使用Bit快速将其转换为共享组件,以便在不同位置使用,开发和同步。 试试吧。
让我们开始吧
在开始之前, 让我们构建一个简单的web服务端,首先用npm下载express到你的电脑当中,然后打开命令行工具,执行以下语句
$ npm install express
然后,新建一个文件夹叫做 jwt-auth. 当然你也可以命名为其他名字
$ mkdir jwt-auth
$ cd jwt-auth
在这个文件夹里新建一个文件叫做index.js . 这个文件是用来写我们的代码并且启动一个web服务器,并且包含一个独立的路由能够显示当前日期和时间还有一个404页面的处理程序,
打开一个编辑器,写如下的代码
const express = require("express");
const app = express();
const PORT = 8888;
app.get('/time', (req, res) => {
const time = (new Date()).toLocaleTimeString();
res.status(200).send(`The Time is ${time}`);
});
在这里,我们首先导入我们刚刚安装的express
库。 然后我正在创建一个名为app
的const
,它将使express
库。 我还创建了另一个名为PORT
的常量,它将包含我们的服务器将运行的端口号。 我选择了8888作为端口号。 如果您愿意,也可以使用任何其他端口号。
接下来,我创建了一个名为time
的新路由。 此路由以响应
和请求
作为参数进行回调。 简而言之,此路由将向用户显示当前本地时间。
当想要服务器把我们带到除了time
之外的任何路由时,我们还要添加一个路由。 这被称为catchall路由。 我希望服务器在此路由上返回404错误。 要实现此功能,请将以下代码写入index.js
文件:
app.get("*", (req, res) => {
res.sendStatus(404);
});
还有最后一件事要做。 我们没有告诉我们的服务器要监听哪个端口。 我们已将端口号初始化为8888.但我们还没有在代码中实际使用此定义。 为此,请使用app.listen
方法,如下所示:
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
完成后,我们可以通过命令行输入node来启动服务器。 然后,转到localhost:8888
,您会发现它显示Not Found
消息。 添加/时间
到URL,它会显示本地时间,如下所示:
最终我们已经建立了一个express服务器,它将向我们在/time
路由显示当地时间以及任何其他路由上的404错误。
**添加一个登陆路由
由于本文是关于JWT身份验证的,因此我们实现一个名为login的路由。 与之前使用get
和listen
的部分中的路由不同,此路由将使用post
创建。
app.post("/login", (req, res) => {
const user = req.body.username;
res.status(200).send(`User's name is ${user}`);
})
但目前我们的服务器无法读取请求的正文。 为了解决这个问题,我们将安装一个名为body-parser
的新中间件。
$ npm install body-parser
然后就像我们使用express库一样,使用require语法将其导入index.js文件。
const bodyParser = require("body-parser");
我们现在可以告诉express使用body-parser来处理所有JSON响应,如下所示:
app.use(bodyParser.json());
现在我们通过node.来启动服务器
为了测试这个新的路由,我们需要用到
,如果你还没有安装的话,下载一下这个吧。
在POSTMAN中,我们创建一个post请求到这个登陆路由,如下所示:
在这个请求体内,创建一个如下的json:
点击发送应该得到以下响应:
发布JWT
现在我们已经构建了一个可以处理GET和POST请求的简单服务器,让我们构建一个简单的JWT发布。
让我们首先创建一个名为users
的新数组,其中包含几个用户及其密码,如下所示:
const users = [
{id: 1, username: "clarkKent", password: "superman"},
{id: 2, username: "bruceWayne", password: "batman"}
];
让我们重写 login
路由,首先我们需要检查提交上来的请求里面是否同时包含username
和 password
,如果不是的话,那么服务端需要返回400状态码。
app.post("/login", (req, res) => {
if (!req.body.username || !req.body.password) {
res.status(400).send("Error. Please enter the correct username and password");
return;
}
然后如果这个请求有效,我们需要检查是否用户名在我们的users
数组里面,
在if语句下面的相同的login
路由中写:
const user = users.find((u) => {
return u.username === req.body.username && u.password === req.body.password;
});
如果这个用户并未在我们的users
数组当中,我们需要返回401的状态码,同样是在/login
路由中:
在继续进行之前,我们下载另一个库叫做 jsonwebtoken
$ npm install jsonwebtoken
在index.js文件的头部,用require语句引入jsonwebtoken
,
const jwt = require("jsonwebtoken");
我们将使用此库为每个有效用户创建JSON Web令牌。 为此,我们将使用jsonwebtoken
库中的sign
方法创建一个名为token
的新const
。 请注意,我们仍然在/ login
路由中编写代码。
const token = jwt.sign({
sub: user.id,
username: user.username
}, "mykey", {expiresIn: "3 hours"});
res.status(200).send({access_token: token})
现在去到POSTMAN,发送一个post请求,请求中带有如下的json结构
{
"username": "clarkKent",
"password": "superman",
}
运行结果会是如下的一个JSON Web Token
如果你复制这个access_token
到 JWT.IO Debugger中,你会看到相同的用户名和密码,只不过多了一些其他的消息,
旁注 - CORS
在某些情况下,您的应用尝试访问的API运行在与应用程序不同的服务器上,将返回某种“无法加载”错误。
为了防止这种情况发生,我们可以安装另一个名为cors的库
$ npm install cors
在index.js头部,用require语句引入这个库
const cors = require("cors");
然后类似于我们对body-parser库所做的,我们将告诉express使用cors,如下所示:
app.use(cors());
使用JWT为API提供用户访问权限
在这里,我们将创建一个包含两个路由的新API。 第一个路由将是公共的,而第二个将要求用户使用JWT进行身份验证以便访问它。
让我们在jwt-auth文件夹中创建一个名为api.js的新文件。 在此文件中,编写以下启动代码:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const PORT = process.env.API_PORT || 8888;
app.use(bodyParser.json());
app.get("*", (req, res) => {
res.sendStatus(404);
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
让我们创建一个路由名叫 '/asset' 这个是公共路由,将会直接返回一个200的状态码
app.get("/asset", (req, res) => {
res.status(200).send("Everybody can see this");
});
第二个秘密路由是/asset/secret
,它将使用jwtCheck进行保护,如下所示:
app.get("/asset/secret", jwtCheck, (req, res) => {
res.status(200).send("Only logged in people can see me");
});
因为index.js文件已经设置启动在8888端口,我们需要把这个文件设置在其他端口,为了实现,我们需要打开命令行工具,然后运行如下代码:
$ export API_PORT=5555
尽管我们已经说过/ asset / secret路由是安全的,但我们还没有真正实现它。 为此,我们需要安装另一个名为express-jwt
的中间件库。
$ npm install express-jwt
在index.js头部,用require语句引入这个库
const expressjwt = require("express-jwt");
我们将使用此库来定义jwtCheck
。 我们将使用jwtCheck
来检查签名是否与我们从身份验证服务器获得的签名相匹配。 如果你还记得,我们把它命名为“mykey”。
const jwtCheck = expressjwt({
secret: "mykey"
});
运行node api.js
命令, 检查这个权限的运行情况是否正常, 去POSTMAN发送get请求到localhost:5000/asset
,他的响应应该是Everybody can see this
然后你发送请求到localhost:5000/asset/secret
,你应该会看到一个大的错误提示:
要解决此问题,请转到POSTMAN中的Authentication选项卡,然后选择Type as Bearer Token。 然后输入Token的值为我们在前面部分中算出的值。
结论
与其他Web令牌(如简单Web令牌(SWT)或安全断言标记语言(SAML))相比,JWT更简单,因为它基于JSON,比XML更容易理解。
如果我们对JSON进行编码,它的大小将比SAML更小,从而更容易传入HTML和HTTP环境。
安全方面,SWT使用单个密钥,而JWT和SAML都使用公钥和私钥对进行更好的身份验证。
从使用的角度来看,JWT用于互联网规模。这意味着在用户的设备上处理更容易,无论是笔记本电脑还是移动设备。
除了身份验证之外,JSON Web令牌是一种在多方之间传输数据的绝佳方式。 JWT具有签名这一事实使每个人都可以更轻松地识别信息发送者。您只需要正确的密钥即可
JWT验证的更多相关文章
- 踩坑之路---JWT验证
使用JWT验证客户的携带的token 客户端在请求接口时,需要在request的head中携带一个token令牌 服务器拿到这个token解析获取用户资源,这里的资源是非重要的用户信息 目前我的理解, ...
- golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息
golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...
- springboot成神之——basic auth和JWT验证结合
本文介绍basic auth和JWT验证结合 目录结构 依赖 config配置文件WebSecurityConfig filter过滤器JWTLoginFilter filter过滤器JWTAuthe ...
- webapi中使用token验证(JWT验证)
本文介绍如何在webapi中使用JWT验证 准备 安装JWT安装包 System.IdentityModel.Tokens.Jwt 你的前端api登录请求的方法,参考 axios.get(" ...
- 手写jwt验证,实现java和node无缝切换
前言 前端时间和我朋友写了一个简易用户管理后台,功能其实很简单,涉及到的技术栈有:vue+elementUI,java+spring MVC以及node+egg,数据库用的mysql,简单方便. 一开 ...
- Nginx实现JWT验证-基于OpenResty实现
介绍 权限认证是接口开发中不可避免的问题,权限认证包括两个方面 接口需要知道调用的用户是谁 接口需要知道该用户是否有权限调用 第1个问题偏向于架构,第2个问题更偏向于业务,因此考虑在架构层解决第1个问 ...
- Jwt验证登录
练习模板:https://gitee.com/zh1446802857/swagger-multi-version-api.git Jwt在我的 认知里,是一套门锁.别人(用户)需要用到你的接口 的时 ...
- jwt验证登录信息
为什么要告别session?有这样一个场景,系统的数据量达到千万级,需要几台服务器部署,当一个用户在其中一台服务器登录后,用session保存其登录信息,其他服务器怎么知道该用户登录了?(单点登录), ...
- spring集成jwt验证方式,token验证
为什么要告别session?有这样一个场景,系统的数据量达到千万级,需要几台服务器部署,当一个用户在其中一台服务器登录后,用session保存其登录信息,其他服务器怎么知道该用户登录了?(单点登录), ...
随机推荐
- VS Code 快捷键使用小技巧
相关文档 官方文档(英文版):Documentation for Visual Studio Code 中文文档(未完成):GitHub - jeasonstudio/CN-VScode-Docs: ...
- DAG 动态规划 巴比伦塔 B - The Tower of Babylon
题目:The Tower of Babylon 这是一个DAG 模型,有两种常规解法 1.记忆化搜索, 写函数,去查找上一个符合的值,不断递归 2.递推法 方法一:记忆化搜索 #include < ...
- centos7下安装docker(3.1创建镜像commit)
docker commit创建镜像 步骤:1.运行容器 2.修改容器 3.将容器保存为镜像 1. 注:-it是以交互模式进入容器,并打开终端 2.安装一个vim进行修改镜像 yum install - ...
- UVA12171-Sculpture(离散化+floodfill)
Problem UVA12171-Sculpture Accept: 196 Submit: 1152 Time Limit: 3000 mSec Problem Description Imagi ...
- ORB-SLAM2(1) Linux下配置和编译
ORB-SLAM2 官网:https://github.com/raulmur/ORB_SLAM2 配置教程:http://blog.csdn.net/zzlyw/article/details/54 ...
- Qt 编程指南 3_1 按钮弹窗手动和自动关联示例
触发的两种模式 connect() 和 on_控件ID_控件函数(参数) 两者优缺点对比: 虽然 Qt 有比较好用的自动关联大法,但自动关联不是万能的,尤其是涉及到多个窗体的时候,比如 A 窗体私有按 ...
- 分布式爬虫之elasticsearch基础1
一:搜索引擎elasticsearch介绍 Elasticsearch 是一个全文搜索引擎,可以快速地储存.搜索和分析海量数据. 二:应用场景 海量数据分析引擎 站内搜索引擎 数据仓库 三:安装 我们 ...
- 解决VC++6.0打开文件或添加文件到工程出错的问题
相信很多朋友在安装VC++6.0之后,发现无法使用打开文件命令.同时,打开了工程,却无法实现文件添加到工程的问题.一旦进行如此操作,便会出现应用程序错误,需要关闭应用程序.为此,不胜其烦.更有甚者,以 ...
- vmware 12中安装苹果系统
我用的系统是win10... 一.所需软件: 1.下载并安装VMware Workstation Pro 12 密码:7ybc和序列号 密码是:bwm0 2.下载unlocker 203(for OS ...
- Linux_软件安装管理
开始学习rpm,yum等命令的使用,下面的地址可供你学习 大部分都大同小异! 感谢作者:https://segmentfault.com/a/1190000011200461