react+koa+vite前后端模拟jwt鉴权过程
路由组件(生成token)
const Router = require('@koa/router')
const jwt = require('jsonwebtoken');
const router = new Router()const mockDbUserInfo = [{nickname: 'xxxliu',username: 'Tom',password: 123456,icon: 'url1'},{nickname: 'xxx',username: 'John',password: 123456,icon: 'url2'},
]const secretKey = 'xxxliu key';router.post('/api/home', async ctx => {ctx.response.body = {msg: '主页',code: 'success'}
})router.post('/api/login', async ctx => {try {const { username, password } = ctx.request.body;//mock查db操作const { nickname, password: pwd, icon } = mockDbUserInfo.find(item => item.username === username) || {};if (!nickname) {ctx.response.body = {msg: "不存在该用户",code: "failed",};return;}if (pwd !== password) {ctx.response.body = {msg: "密码输入错误",code: "error",};return;}// 构建 JWT 头部const header = {alg: 'HS256', // 签名算法,例如使用 HMAC SHA-256typ: 'JWT', // Token 的类型};const payload = {username};const options = {expiresIn: '1h', // 设置 JWT 的过期时间header, // 将 header 选项包含在 options 中};//生成tokenconst token = jwt.sign(payload, secretKey, options);ctx.response.body = {nickname,icon,code: "success",msg: "登录成功",};ctx.cookies.set('myToken',token,{ maxAge: 1 * 60 * 60 * 1000, httpOnly: false})} catch (error) {ctx.response.body = error;}
})module.exports = router;
token解析
const jwt = require('jsonwebtoken');const secretKey = 'xxxliu key';
const verifyToken = async (ctx, next) => {try {const { url } = ctx.request;//走登录页不鉴权const requestUrl = url.split("?")[0];const noVerifyList = ["/api/login"];const noVerify = noVerifyList.includes(requestUrl);if (noVerify) {await next();} else {//拿到请求头的参数const authorization = ctx.request.header["authorization"];const username = ctx.request.body["username"];if (authorization.startsWith('Bearer ')) {const token = authorization.slice(7);const { exp, username: userName } = jwt.verify(token, secretKey) || {};if (userName !== username) {ctx.response.body = {code: "error",msg: "无效的token, 请重新登录",};}else if (exp * 1000 > Date.now()) {ctx.response.body = {code: "error",msg: "登录信息已过期, 请重新登录",};} else {await next();}} else {ctx.response.body = {code: "error",msg: "无效的token, 请重新登录",};}}} catch (err) {if (err.name == "TokenExpiredError") {ctx.body = {code: "error",msg: "token已过期, 请重新登录",};} else if (err.name == "JsonWebTokenError") {ctx.body = {code: "error",msg: "无效的token, 请重新登录",};}}};module.exports = verifyToken;
注册中间件
const Koa = require('koa')
const path = require('path')
const sendfile = require('koa-sendfile')
const static = require('koa-static')
const bodyParser = require("koa-bodyparser")
const router = require('./server/api-router.js')
const assets = require('./server/assets-router')
const verifyToken = require('./server/verifyToken.js');
const app = new Koa()// static
app.use(static(path.resolve(__dirname, 'public')))//body
app.use(bodyParser());//midware auth
app.use(verifyToken);// api
app.use(router.routes()).use(router.allowedMethods())// assets
app.use(assets.routes()).use(assets.allowedMethods())// 404
app.use(async (ctx, next) => {await next()if (ctx.status === 404) {await sendfile(ctx, path.resolve(__dirname, 'public/index.html'))}
})app.listen(3000, () => {console.log(`> http://127.0.0.1:3000`)
})
前端请求(登录+打开主页)
import { useState, useEffect } from 'react'
import getTokenFromCookie from './tools'
function App() {const [response, setResponse] = useState({})const token = getTokenFromCookie();useEffect(() => {fetch('/api/login', {method: 'post',headers: {'Content-Type': 'application/json','Authorization': `Bearer ${token}`,},body: JSON.stringify({username: 'Tom',password: 123456})}).then(res => res.json()).then(res => {setResponse(res);})// fetch('/api/home', {// method: 'post',// headers: {// 'Content-Type': 'application/json',// 'Authorization': `Bearer ${token}`,// },// body: JSON.stringify({// username: 'Tom',// password: 123456// })// })// .then(res => res.json())// .then(res => {// setResponse(res);// })}, [])const { nickname, icon, msg } = response || {}return (<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{nickname ? <div><h1>icon: {icon}</h1><h1>nickname: {nickname}</h1><h1>msg: {msg}</h1></div>: <h1>msg: {msg}</h1>}</div>)
}export default App相关文章:
react+koa+vite前后端模拟jwt鉴权过程
路由组件(生成token) const Router require(koa/router) const jwt require(jsonwebtoken); const router new Router()const mockDbUserInfo [{nickname: xxxliu,username: Tom,password: 123456,icon: url1},{nickname: xxx,username: John,passw…...
VK1616是LED显示控制驱动电路/LED驱动IC、数显驱动芯片、数码管驱动芯片
产品品牌:永嘉微电/VINKA 产品型号:VK1616 封装形式:SOP16 产品年份:新年份 概述:VK1616是一种数码管或点阵LED驱动控制专用芯片,内部集成有3线串行接口、数据锁存器、LED 驱动等电路。SEG脚接LED阳极&a…...
开箱报告,Simulink Toolbox库模块使用指南(五)——S-Fuction模块(C MEX S-Function)
文章目录 前言 C MEX S-Function 算法原理 原始信号创建 编写S函数 仿真验证 Tips 分析和应用 总结 前言 见《开箱报告,Simulink Toolbox库模块使用指南(一)——powergui模块》 见《开箱报告,Simulink Toolbox库模块使用…...
摄像头的调用和视频识别
CV_tutorial3 摄像头调用实时播放保存视频 运动目标识别帧差法背景减除法 摄像头调用 创建视频捕捉对象:cv2.VideoCapture() 参数为视频设备的索引号,就一个摄像投的话写0默认; 或者是指定要读取视频的路径。 实时播放 import cv2 import …...
多通道分离与合并
目录 1.多通道分离split() 2.多通道合并merge() 3.Android JNI demo 1.多通道分离split() void cv::split ( InputArray m, OutputArrayOfArrays mv ) m:待分离的多通道图像。 mv:分离后的单通道图像,为向量vector形式。 2.多通道合并merge…...
JOJO的奇妙冒险
JOJO,我不想再做人了。 推荐一部动漫 JOJO的奇妙冒险 荒木飞吕彦创作的漫画 《JOJO的奇妙冒险》是由日本漫画家荒木飞吕彦所著漫画。漫画于1987年至2004年在集英社的少年漫画杂志少年JUMP上连载(1987年12号刊-2004年47号刊),2005年后在集英…...
LeetCode56.合并区间
这道题我想了一会儿,实在想不到比较好的算法,只能硬着头皮写了,然后不断的debug,经过我不懈的努力,最后还是AC,不过效率确实低。 我就是按照最直接的方法来,先把intervals数组按照第一个数star…...
【内推码:NTAMW6c】 MAXIEYE智驾科技2024校招启动啦
MAXIEYE智驾科技2024校招启动啦【内推码:NTAMW6c】 【招聘岗位超多!!公司食堂好吃!!】 算法类:感知算法工程师、SLAM算法工程师、规划控制算法工程师、目标及控制算法工程师、后处理算法工程师 软件类&a…...
Python框架【模板继承 、继承模板实战、类视图 、类视图的好处 、类视图使用场景、基于调度方法的类视图】(四)
👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误…...
对于前端模块化的理解与总结(很全乎)
目录 模块化的好处 模块化的commonJS导入导出 暴露(导出)模块:module.exports value或exports.xxx value 导入模块——使用 es6模块化 方法一逐个导出 方法二默认导出 方法三 方法四 方法五 export 和import 同时存在 多个文件导出到一个文件后在相关文件…...
NewStarCTF 2022 web方向题解 wp
----------WEEK1---------- BUU NewStarCTF 公开赛赛道 WEEK1 [NotPHP] 先看题目,要传参加绕过。 分析一下代码:首先get一个datadata://test/plain,Wel…。然后key1和2用数组可以绕过。num2077a可以绕过弱类型。eval()中的php语句被#注释了,…...
WebGL矩阵变换库
目录 矩阵变换库: Matrix4对象所支持的方法和属性如表所示: 方法属性规范: 虽然平移、旋转、缩放等变换操作都可以用一个44的矩阵表示,但是在写WebGL程序的时候,手动计算每个矩阵很耗费时间。为了简化编程…...
block层:8. deadline调度器
deadline 源码基于5.10 0. 私有数据 struct deadline_data {/** run time data*//** requests (deadline_rq s) are present on both sort_list and fifo_list*/struct rb_root sort_list[2];struct list_head fifo_list[2];/** next in sort order. read, write or both ar…...
DTO,VO,PO的意义与他们之间的转换
DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的性能和降低网络负…...
Java 集合框架2
一、关于set接口的常用类 1.HashSet类 用来处理无序的单列数据,没有重复的元素,重复的元素算一个 i.构造方法 //HashSet类是set接口的子类,是无序的单列数据,没有重复的元素,重复的元素算一个 //HashSet的构造方法 //HashSet() …...
2024王道408数据结构P144 T16
2024王道408数据结构P144 T16 思考过程 首先看题目,要求我们把二叉树的叶子结点求出来并且用链表的方式存储,链接时用叶结点的右指针来存放单链表指针。我们很清楚可以看出来能用中序遍历递归的方式实现,因为第一个叶子结点在整棵树的最左下…...
【ARM Coresight 系列文章 22 -- linux frace 与 trace-cmd】
文章目录 ftrace 介绍trace-cmd 介绍trace-cmd 常用跟踪事件ftrace 与 trace-cmd 关系ftrace 编译依赖 ftrace 介绍 ftrace 是 Linux 内核中的一个跟踪工具,主要用于帮助开发者分析和调试内核的行为。ftrace 的名字来源于 “function tracer”,它最初是…...
MyBatis的一级缓存和二级缓存是怎么样的?
目录 1. 一级缓存 2. 一级缓存失效的几种情况 3. 二级缓存 4.二级缓存失效的情况 5. 二级缓存的相关配置 6. 缓存的查询顺序 MyBatis 的缓存共分为一级缓存和二级缓存。 1. 一级缓存 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询到的数据会被缓…...
下载的文件被Windows 11 安全中心自动删除
今天从CSDN上下载了自己曾经上传的文件,但是浏览器下载完之后文件被Windows安全中心自动删除,说是带病毒。实际是没有病毒的,再说了即便有病毒也不应该直接删除啊,至少给用户一个保留或删除的选项。 研究了一番,可以暂…...
【Java List与数组】List<T>数组和数组List<T>的区别(124)
List数组:存储List的数组,即:数组中的元素是:List; 数组List:存储数组的List,即:List中的数据是类型的数组; 测试案例: import java.util.ArrayList; impor…...
独立开发者如何借助Taotoken管理多个AI侧项目
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 独立开发者如何借助Taotoken管理多个AI侧项目 作为一名独立开发者,同时维护多个使用大模型的小型项目是常态。你可能有…...
数据结构:3.包装类和泛型
【目标】1.了解包装类 2. 以 能阅读java集合源码 为目标学习泛型3.了解泛型1.包装类(Wrapper Class)1.1 引出包装类1.1.1 什么是包装类?一句话: 包装类就是把 Java 的 8 种基本数据类型(int, double, char 等&a…...
告别手动描图!用AutoCAD Civil 3D 2024快速搞定两期土方横断面对比(附模板)
告别手动描图!用AutoCAD Civil 3D 2024快速搞定两期土方横断面对比(附模板) 在土木工程领域,土方量计算是项目成本控制与进度管理的关键环节。传统CAD手动绘制横断面的方式不仅耗时费力,更难以应对设计变更带来的反复修…...
从星座图乱麻到清晰:手把手教你用OpenOFDM搞定Wi-Fi信号频偏校正
从星座图乱麻到清晰:手把手教你用OpenOFDM搞定Wi-Fi信号频偏校正 当你第一次用软件无线电(SDR)捕获Wi-Fi信号时,看到的星座图像是被猫抓过的毛线团——杂乱无章的斑点毫无规律地散布在平面上。这种令人沮丧的场景,正是…...
开发雨天居家室内活动推荐程序,根据人数年龄自动生成雨天居家休闲创意活动。
一个完全去营销化、偏工程与创业实验视角的 Python 示例项目,定位为课程级 MVP 原型,不绑定任何平台、不推荐商品、不引导消费。雨天居家室内活动推荐程序——基于人数与年龄的规则推荐系统实验一、实际应用场景描述在下雨天气,家庭或室友常面…...
2026降AI率工具红黑榜:降AIGC工具怎么选?照着用就行!
2026年论文降AI率工具竞争激烈,千笔AI、ThouPen、豆包凭借精准适配国内高校AI率检测规范成为红榜首选。黑榜需警惕低质免费工具、无正规检测对接、改写痕迹生硬的产品。选择时应综合考量(降AI效果 - 学术合规性 - 使用成本)三维模型ÿ…...
2026实测:专业降AI率软件选这款就对了
2026 年降 AIGC 工具已经从“机械式语义调整”进化为多维度智能优化系统,核心评估指标涵盖 AI 痕迹去除精准度、学术表达一致性、格式结构完整性、长段落逻辑稳定性、内容改写适配性以及高校检测合规性。本次测评覆盖 5 款主流工具,测试场景包括中英文论…...
ATxmega时钟与GPIO配置详解:从原理到实战调试
1. 项目概述:从零认识ATxmage的时钟与GPIO最近在捣鼓一块ATxmage的开发板,很多刚入门的朋友拿到手,面对密密麻麻的引脚和一堆陌生的寄存器,往往不知道从哪里下手。其实,玩转任何一款微控制器,最核心、最基础…...
告别卡顿!用ZLMRTCClient.js和Vue3打造超低延迟WebRTC监控播放器(附完整代码)
超低延迟WebRTC监控播放器:基于ZLMRTCClient.js与Vue3的工程实践 在安防监控、智慧园区等对实时性要求极高的场景中,传统流媒体方案如HLS或FLV往往面临3-5秒甚至更高的延迟。这种延迟在关键场景下可能导致严重后果——当监控画面显示"一切正常"…...
全志T153异构处理器在工业控制与边缘计算中的应用实战解析
1. 项目概述:一颗为工业场景量身定制的“中国芯”最近在关注国产工业控制核心板的朋友,应该都注意到了米尔电子和全志科技这对“老搭档”又出新作了。继T113、T507这些在工控、边缘计算领域已经打下不错口碑的系列之后,他们这次联手推出了基于…...
