当前位置: 首页 > news >正文

jwt的基本介绍

说出我的悲惨故事给大家乐呵乐呵:公司刚来了一个实习生,老板让他写几个接口给我,我页面还没画完呢。他就把接口给我了,我敲开心,第一次见这么高效率的后端。但我很快就笑不出来了。他似乎不知道HTTP通信是无状态的。他不能识别登录的用户,只会把数据添加进数据库。虽然网络上有很多资料,但为了省时间,我打算写了简单的demo和他探讨一下,可能不太规范,希望大家多多指教。

JSON Web Token 简介

JSON Web Token 简称JWT,在HTTP通信过程中,进行身份认证。
好了,就说这么多,先上代码,因为有些概念说不好会把人转晕,手动操作后就容易理解了:
请添加图片描述

 /*** * 实现流程:* 用户登录,服务器产生一个token(加密字符串)发送给前端,* 前端将token保存(想存哪就存哪)* 前端发起数据请求时携带token* 服务端验证token是否合法,合法继续操作,不合法终止操作* token的使用场景:无状态请求,保持用户的登录状态,第三方登录(token+auth2.0)*/async function onFinished(e){//提交表单默认会跳转到新的页面,或者刷新整个页面//1.阻止默认事件e.preventDefault();//2.定义formData对象let formData = new FormData(e.target);let username = formData.get('username');let password = formData.get('password');console.log(username, password);try{const result = await  login(username, password);//save token to local storagestorage.set('token', result.token)console.log(result)}catch(e){console.log(e)}}
export function login(username,password) {return axios.post('http://192.168.50.225:3000/login',{username,password})
}

node 中 jwt的使用

var express = require('express');
const jwt = require('jsonwebtoken');//加载包
const fs = require('fs');
const { dirname } = require('path');
var router = express.Router();
/*** login*/router.post('/login', function(req, res, next){console.log(req.body)//{ username: 'eqw', password: 'qweq' }//产生token默认算法hs256/*** 此方法接收两个参数* 第一个是要加密保存的数据(一个对象,不要放隐秘性的数据,如密码),* 第二个是要加密的私钥(一个字符串,越乱越好)*/let token=jwt.sign(req.body,'rieryowqerdfkjhasdfqr');console.log(token);//返回一个加密字符串// 服务器签发的token//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiMTIzIiwiaWF0IjoxNTcwMDc2NjU5fQ.3FT6v8zVptdWGBILD1m1CRY6sCP1I3E947krUh_E3//我就不链接数据库了,将数据存入本地文件//fs.appendFile()方法的作用是:将指定的内容追加到文件中。如果该文件不存在,则创建该文件:fs.appendFile(__dirname+'/data.txt', JSON.stringify(req.body), function (err) {if (err) throw err;console.log('Saved!');});res.send({token,status:200,message:'success'})
});module.exports = router;

前端登录:
只做演示实验,前端没有对密码加密勿怪
请添加图片描述
请添加图片描述

前端请求数据:
request.js

import axios from 'axios';
import { storage } from '../utils/localStorage';axios.defaults.timeout = 5000
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8';//在请求头里验证是否有token
axios.interceptors.request.use(function (config) {const token=storage.get('token');console.log(token)if(token){config.headers['Authorization'] = 'Bearer ' + token;}else{//重定向到登录界面}return config;}, error => {console.log(error)Promise.reject(error)})//请求响应axios.interceptors.response.use(function (response) {if (response.status === 401) {//}return response;}, function (error) {return Promise.reject(error)})export default axios;

user.js

import axios from '../request';export function login(username,password) {return axios.post('http://192.168.50.228:3000/login',{username,password})
}export function getInfo(){return axios.get('http://192.168.50.228:3000/info');
}

后端验证token:

/*** 请求数据*/router.get('/info',function(req,res,next){//客户端请求数据的时候验证token//客户端传递过来的tokenconsole.log(req.headers.authorization)let tokens=req.headers.authorization.split(' ')[1];/*** verify接收两个参数,* 第一个参数是客户端传递过来的token,* 第二个参数是加密时的私钥;* 第三个参数是回调函数*/jwt.verify(tokens,'rieryowqerdfkjhasdfqr',function (err,data) {console.log(err);//签名通过返回null,签名不通过返回err(JsonWebTokenError: invalid signature)	console.log(data);//	通过返回解密数据,失败返回unfinishedfs.readFile(__dirname+'/data.txt',function(err, datas){if(err){res.writeHead(505,{'Content-Type':'text/html;charset=utf-8'});res.end({message:'500 服务器内部错误'})return;}//console.log(data,'database');//<Buffer 7b 22 75 73 65 72 6e 61 6d 65 22 3a 22 6d 69 61 6f 22 2c 22 70 61 73 73 77 6f 72 64 22 3a 22 6d 69 61 6f 31 32 33 22 7d>console.log(JSON.parse(datas.toString()));//从文件中直接读取到时Buffer ,把Buffer转成datas.toString() 字符串const user=JSON.parse(datas.toString());console.log(user.username===data.username,'-_-');if(user.username===data.username){res.send({data:[{id:1,name:"纸崩"},{id:2,name:"当怪兽来敲门"}]})}else{res.writeHead(404,{'Content-Type':'text/html;charset=utf-8'});res.end({message:'token is error'})}})});
});

前端请求:
请添加图片描述
现在在来看概念:
HTTP通信是无状态的,因此客户端的请求到了服务端处理之后是无法返回给原来的客户端的。so,需要对访问的客户进行识别。
常用的做法是session机制:客户端在服务端登陆成功之后,服务端会生成一个sessionID,返回给客户端,客户端将sessionID保存到cookie中,再次发起请求的时候,携带cookie中sessionID到服务端,服务端会缓存该session,当客户端请求到来的时候,服务端就知道是哪个用户的请求,并将处理的结果返回给客户端,完成通信。
通过上面的分析,可以知道session存在以下问题:

  • session保存在服务端,当客户访问量增加时,服务端就需要存储大量的sesion会话,对服务器又很大的考验;

所以这里采用了JSON Web Token,JSON Web Token是怎么做的?
1.客户端通过用户名和密码登录服务器
2.服务端对客户端进行身份验证
3.服务端对该用户生成Token,返回给客户端
4.客户端将Token保存到本地浏览器,一半保存cookie中
5.客户端发起请求,需要携带该tooken
6.服务端收到请求后,首先验证该Token,之后返回数据。
服务端不需要存储token,只需要对Token中携带的信息进行验证即可;
无论客户端访问后台的哪台服务器,只要可以通过用户信息的验证即可。

参考资料:https://blog.csdn.net/weixin_44036436/article/details/102004739

相关文章:

jwt的基本介绍

说出我的悲惨故事给大家乐呵乐呵&#xff1a;公司刚来了一个实习生&#xff0c;老板让他写几个接口给我&#xff0c;我页面还没画完呢。他就把接口给我了&#xff0c;我敲开心&#xff0c;第一次见这么高效率的后端。但我很快就笑不出来了。他似乎不知道HTTP通信是无状态的。他…...

常见Vue事件修饰符浅析

一、.stop修饰符 .stop修饰符代表event.stopPropagation()&#xff0c;加上这个修饰符&#xff0c;就等于在方法中加上了这句代码。 <!--阻止单击事件继续传播--> <a click.stop"doThis"></a>上面的代码等同于如下代码。 <!--阻止单击事件继…...

怎样开始用selenium进行自动化测试?

如果您刚开始使用 Selenium 进行自动化测试&#xff0c;以下是建议的步骤。 1、安装 Selenium 首先&#xff0c;您需要安装 Selenium。Selenium 支持多种编程语言&#xff0c;如 Python、Java、C# 等。可以通过 pip 命令在 Python 中安装 Selenium&#xff1a; pip install …...

二维数组多次排序 或 嵌套list多次排序

可以排序int[ ][ ]的顺序&#xff0c;也可以排序List<List<Integer>> 顺序 为便于理解&#xff0c;以力扣原题为例&#xff1a;1333.餐厅过滤器 原题中给了一个双重数组&#xff0c;并要求返回一个List<Integer>。 方法1&#xff1a; 会用流的&#xff0c…...

Flutter - 波浪动画和lottie动画的使用

demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新&#xff0c;请前往github查看最新代码 波浪动画三方库wave lottie动画 Lottie 是 Airbnb 开发的一款能够为原生应用添加动画效果的开源工具。具有丰富的动画效果和交互功能。 # 波浪动画 https://pub-web…...

忘记压缩包密码?解决方法一键找回,省时又便捷!

使用在线rar/zip解密工具&#xff0c;找回rar/zip密码并解密压缩包的方法非常简单。具体步骤如下&#xff1a;首先&#xff0c;在百度上搜索“密码帝官网”&#xff0c;这是一个专业的解密服务网站。然后&#xff0c;点击搜索结果中的链接&#xff0c;进入官网首页。在页面上方…...

“UTONMOS”掀起元宇宙游戏热潮,全球发展前景广阔

我们都知道&#xff0c;市面上无论是PC端的网游还是移动端手游&#xff0c;它如果要做到源源不断的内容输出&#xff0c;不仅取决于游戏公司产品质量和业绩&#xff0c;也与公司的决策和市场沟通密不可分。 元宇宙游戏市场受到关注 近年来&#xff0c;元宇宙游戏市场逐渐升温…...

用idea工具scala 和 Java开发 spark案例:WordCount

目录 一 环境准备 二 scala代码编写 三 java 代码编写 一 环境准备 创建一个 maven 工程 添加下列依赖 <dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.12</artifactId><version>${spark.version}</vers…...

【git merge/rebase】详解合并代码、解决冲突

目录 1.概述 2.merge 3.rebase 4.merge和rabase的区别 5.解决冲突 1.概述 在实际开发中&#xff0c;一个项目往往是多个人一起协作的&#xff0c;头天下班前大家把代码交到远端仓库&#xff0c;第二天工作的第一件事情都是从服务器上拉最新的代码&#xff0c;保证代码版本…...

nrm,npm源的管理工具

npm手动切换淘宝源 查看当前的仓库 npm config get registry设置成淘宝源 npm config set registry https://registry.npmmirror.com/设置回官方源 npm config set registry https://registry.npmjs.org/手动切换不免不太方便&#xff0c;而且网上很多资料淘宝源还是过期的链接…...

HarmonyOS/OpenHarmony原生应用-ArkTS万能卡片组件Stack

堆叠容器&#xff0c;子组件按照顺序依次入栈&#xff0c;后一个子组件覆盖前一个子组件。该组件从API Version 7开始支持。可以包含子组件。 一、接口 Stack(value?: { alignContent?: Alignment }) 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 二、…...

腾讯云2核4G服务器一年和三年价格性能测评

腾讯云轻量2核4G5M服务器&#xff1a;CPU内存流量带宽系统盘性能测评&#xff1a;轻量应用服务器2核4G5M带宽&#xff0c;免费500GB月流量&#xff0c;60GB系统盘SSD盘&#xff0c;5M带宽下载速度可达640KB/秒&#xff0c;流量超额按照0.8元每GB的价格支付流量费&#xff0c;轻…...

集线器、交换机、路由器是如何转发包的

集线器、交换机、路由器是如何转发包的 集线器交换机MAC地址表的维护 路由器路由表中的信息路由器的包接收操作查询路由表确定输出端口找不到匹配路由时选择默认路由包的有效期通过分片功能拆分大网络包路由器发送操作中的一些特点 参考文档 集线器 集线器是一层&#xff08;物…...

交通物流模型 | MDRGCN:用于多模式交通客流预测的深度学习模型

城市交通拥堵是造成交通事故的重要原因,也是城市发展的主要障碍。通过学习历史交通流数据,我们可以预测未来一些区域的交通流,这对城市道路规划、交通管理、交通控制等都有重要意义。然而,由于交通网络拓扑结构的复杂性和影响交通流的因素的多样性,交通模式往往是复杂多变…...

保研经历分享(一)

这个系列的文章主要是想记录一下自己大学期间最重要的一件事&#xff08;保研!!&#xff09;的经历、过程&#xff0c;外加一些保研流程介绍、面试经验、院校投递、踩坑经历&#xff0c;主要给学弟学妹们避雷&#xff0c;也做一些借鉴吧~ 这一篇主要是对保研过程的一些介绍&…...

【手写数字识别】数据挖掘实验二

文章目录 Ⅰ、项目任务要求任务描述&#xff1a;主要任务要求(必须完成以下内容但不限于这些内容)&#xff1a; II、实现过程数据集描述实验运行环境描述KNN模型决策树模型朴素贝叶斯模型SVM模型不同方法对MNIST数据集分类识别结果分析(不同方法识别对比率表及结果分析) 完整代…...

什么是云计算?云计算简介

其实“云计算”作为一个名词而言&#xff0c;那是相当成功滴。很多人都有听过。但提及云计算”具体是什么?很多人&#xff0c;知其然&#xff0c;却不知其所以然! 利用软件将这些成千上万不可靠的硬件组织成一个稳定可靠的IT系统&#xff0c;以此支撑其公司的IT基础服务。这家…...

Vue路由进阶--VueRouter声明式导航

Vue路由进阶–VueRouter声明式导航 文章目录 Vue路由进阶--VueRouter声明式导航1、声明式导航1.1、导航链接1.2、高亮类名1.3、跳转传参1.4、动态路由参数可选符 1、声明式导航 1.1、导航链接 需求&#xff1a;实现导航高亮效果 vue-router提供了一个全局组件router-link(取…...

Oracle 云服务即将支持 PostgreSQL!

2023 年 9 月 19 日&#xff0c;Oracle 产品团队发布了一篇文章&#xff0c;宣布 Oracle 云基础架构&#xff08;OCI&#xff09;开始提供 PostgreSQL 服务。目前支持的版本为 PostgreSQL 14.9&#xff0c;提供有限支持&#xff0c;12 月份将会提供正式版本。 众所周知&#x…...

数字孪生项目:突破技术难关,引领未来发展

项目背景 数字孪生技术一直在不断发展&#xff0c;为企业提供了无限的潜力和机会。在这个数字时代&#xff0c;公司需要不断进化&#xff0c;以适应市场的需求和客户的期望。北京智汇云舟一直以“视频孪生”为标签&#xff0c;是数字孪生领域的头部企业&#xff0c;拥有强大的…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...