node.js实现分页,jwt鉴权机制,token,cookie和session的区别
文章目录
- 1. 分⻚功能
- 2. jwt鉴权机制
- 1.jwt是什么
- 2.jwt的应用
- 3.优缺点
- 3. cookie,token,session的对比
1. 分⻚功能
- 为什么要分页
- 如果数据量很⼤,⽐如⼏万条数据,放在⼀个⻚⾯显⽰的话显然不友好,这时候就需要采⽤分⻚显⽰的形式。
- 如每次只显⽰10条数据要实现分⻚功能,实际上就是从结果集中显⽰第1(10条记录作为第1⻚,显⽰第11)20条记录作为第2⻚,以此类推。
- 分⻚实际上就是从结果集中截取出第M~N条记录
- 实现
- 前端实现分⻚功能,需要后端返回必要的数据,如总的⻚数,总的数据量,当前⻚,当前的数据
- 后端的处理逻辑
- 获取⽤⼾参数⻚码数page和每⻚显⽰的数⽬pageSize,其中page是必须传递的参数,pageSize为可选参数,默认为10
- 编写SQL语句,利⽤limit和offset关键字进⾏分⻚查询
- 查询数据库,返回总数据量、总⻚数、当前⻚、当前⻚数据给前端
var mysql = require('mysql'); var connection = mysql.createConnection({host : 'localhost',user : 'root',password : '1q2w3e4r',database : 'test' }); connection.connect(); let param = {pageSize: 20,pageNo: 1 } let pageSize = param.pageSize || 10; let start = (param.pageNo - 1) * pageSize; // 每⼀条数据的起始位置start let sql = `select * from students order by score desc limit ${pageSize} OFFSET ${start}` connection.query(sql, function (error, results, fields) {if (error) throw error;console.log(results); }); connection.end();
⾸先确定每⻚显⽰的数量pageSize,当前⻚的索引pageIndex (从1开始),确定LIMIT 和OFFSET 应该设定的值:- LIMIT 总是设定为pageSize
- OFFSET计算公式为pageSize*(pageIndex-1)
确定了这两个值,就能查询出第N⻚的数
2. jwt鉴权机制
1.jwt是什么
JWT(JSONWebToken),本质就是⼀个字符串书写规范,作⽤是⽤来在⽤⼾和服务器之间传递安全可靠的信息。
- JSON Web Tokens 的组成
在其紧凑的格式中,JSON Web Tokens 由三部分组成,由点 (.)分隔,它们是:Header(标头)Payload(有效载荷 ) Signature(签名)- Header
标头通常由两部分组成:令牌的类型,即 JWT,以及所使用的签名算法,例如 HMAC SHA256 或 RSA.
有效示例{ "alg": "HS256", "typ": "JWT" }
- Payload
令牌的第二部分是有效负载,其中包含声明。声明是关于实体(通常是用户)和附加数据的声明。声明分为三种类型:registered(注册声明)、public(公共声明)和private(私人声明).- 已注册声明: 这些是一组预定义的声明,它们不是强制性的,但建议使用,以提供一组有用的、可互操作的声明。其中一些是:
iss(发布者)、
exp(到期时间)、
sub(主题)、
aud(受众)
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。. - 公共声明: 这些可以由使用 JWT 的人随意定义。但是为了避免冲突,它们应该在IANA JSON Web Token注册表中定义,或者定义为包含抗冲突名称空间的 URI。
- 私人声明: 这些是为在同意使用它们的各方之间共享信息而创建的自定义声明,既不是注册声明也不是公共声明
有效载荷示例{ "sub": "1234567890", "name": "John Doe", "admin": true }
- 已注册声明: 这些是一组预定义的声明,它们不是强制性的,但建议使用,以提供一组有用的、可互操作的声明。其中一些是:
- Signature
要创建签名部分,您必须采用编码标头、编码有效负载、秘码、标头中指定的算法,然后对其进行签名.
- Header
2.jwt的应用
- 安装指令
npm install jsonwebtoken
- 加密
参数解析jwt.sign(payload, secretOrPrivateKey, [options, callback])
-
payload:可以是表示有效 JSON 的对象文本、缓冲区或字符串
-
secretOrPrivateKey:是一个字符串(utf-8 编码)、缓冲区、对象或 KeyObject,其中包含 HMAC 算法或 PEM 的密钥 RSA 和 ECDSA 的编码私钥
-
options:
- algorithm(默认:HS256)
- expiresIn:以秒为单位或描述时间跨度 Vercel/ms 的字符串 (60, “2 days”, “10h”, “7d”)。
- notBefore:以秒为单位或描述时间跨度 Vercel/ms 的字符串。
- mutatePayload:如果为 true,则 sign 函数将直接修改 payload 对象。如果您在将声明应用于有效负载之后但在将其编码为令牌之前需要对有效负载的原始引用,这将非常有用。
- allowInsecureKeySizes:如果为 true,则允许将模数低于 2048 的私钥用于 RSA
- allowInvalidAsymmetricKeyTypes:如果为 true,则允许与指定算法不匹配的非对称键。此选项仅用于向后兼容,应避免使用。
var jwt = require('jsonwebtoken');const secret = 'xixi' // 私钥var token = jwt.sign({ name: '西西' }, secret);console.log(token, '1111')var token1 = jwt.sign({ name: '西西' }, secret, { algorithm: 'HS512' });console.log(token1, '2222')// 异步jwt.sign({ name: '西西' }, secret, { algorithm: 'HS512' }, function(err, token) {console.log(token, '3333');});var older_token = jwt.sign({ name: '西西', iat: Math.floor(Date.now() / 1000) - 30 }, secret);console.log(older_token, '4444');
加密时效性var jwt = require('jsonwebtoken');const secret = 'xixi' // 私钥let token = jwt.sign({exp: Math.floor(Date.now() / 1000) + (60 * 60),name: '西西'}, secret);console.log(token, '1111')let token1 = jwt.sign({name: '西西'}, secret, { expiresIn: 60 * 60 });console.log(token1, '2222')let tokenh = jwt.sign({name: '西西'}, secret, { expiresIn: '1h' });console.log(tokenh, '3333')
-
- 解密
参数解析jwt.verify(token, secretOrPublicKey, [options, callback])
- token是 JsonWebToken 字符串
- secretOrPublicKey是一个字符串(utf-8 编码)、缓冲区或 KeyObject,其中包含 HMAC 算法的密钥或 PEM RSA 和 ECDSA 的编码公钥。
- options
- algorithms:包含允许算法名称的字符串列表。例如。[“HS256”, “HS384”]
- audience:如果要检查 audience (),请在此处提供一个值。可以根据字符串、正则表达式或字符串和/或正则表达式列表检查受众。
- complete:返回具有 decoded 的对象,而不仅仅是有效负载的通常内容。{ payload, header, signature }
- issuer(可选):字段有效值的字符串或字符串数组。iss
- jwtid(可选):如果要检查 JWT ID (),请在此处提供字符串值。jti
- ignoreExpiration:如果不验证令牌的过期时间。true
- ignoreNotBefore…
- subject:如果要检查主题 (),请在此处提供一个值sub
- clockTolerance:检查 and 声明时可容忍的秒数,以处理不同服务器之间的小时钟差异nbfexp
- maxAge:令牌仍然有效的最大允许年龄。它以秒或描述时间跨度 vercel/ms 的字符串表示。
- clockTimestamp:应用作所有必要比较的当前时间(以秒为单位)。
- nonce:如果要检查 Claim,请在此处提供 String 值。它用于 ID 令牌的 Open ID。(Open ID 实施说明nonce)
- allowInvalidAsymmetricKeyTypes:如果为 true,则允许与指定算法不匹配的非对称键。此选项仅用于向后兼容,应避免使用。
let token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi6KW_6KW_IiwiaWF0IjoxNzMzMjEwMTc5fQ.24KOMgCK2W6DTUvcotDlP2ciKL_EmA9tTdGJLMZByfc' var decoded = jwt.verify(token, secret); console.log(decoded) // bar let token1 = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi6KW_6KW_IiwiaWF0IjoxNzMzMjEyMDQ4LCJleHAiOjE3MzMyMTU2NDh9.3gDiIfvDNWbn1DR5a0pZtr0Cwkv_aueHZgui8HVluRo' var decoded1 = jwt.verify(token1, secret); console.log(decoded1)
- 校验
使⽤koa-jwt 中间件进⾏验证,⽅式⽐较简单- 安装指令
npm install koa-jwt
- 安装指令
app.use(koajwt({secret: 'test_token' }).unless({ // 配置白名单path: [/\/api\/register/, /\/api\/login/]
- 案例
// 服务代码 const Koa = require('koa') const app = new Koa() var jwt = require('jsonwebtoken'); const Router = require('koa-router') var router = new Router(); // 总路由 const koajwt = require('koa-jwt'); const cors = require('koa2-cors') const secret = 'xixi' // 私钥 // 解决跨域 app.use(cors({origin: function(ctx) {// 这里可以根据实际需求设置允许跨域的域名,或者使用函数进行复杂配置// if (ctx.url === '/crossdomain') {// return 'http://example.com';// }return '*'; // 允许所有域},maxAge: 5, // 表示在5秒内不需要再发送预检请求credentials: true, // 允许cookiesallowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],allowHeaders: ['Content-Type', 'Authorization', 'Accept'], })) // 可以通过unless配置接⼝⽩名单,也就是哪些URL可以不⽤经过校验,像登陆/注册都可以不⽤校验 // 校验的中间件需要放在需要校验的路由前⾯,⽆法对前⾯的URL进⾏校验 app.use(koajwt({secret}))router.post('/api/login_post_json', async (ctx) => {console.log(ctx.request)console.log('abcd');ctx.body = "abcd页"; })app.use(router.routes()).use(router.allowedMethods()); app.listen(8081, function() {console.log('服务启动!端口号:8081') });
// html 代码 <!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title><script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script></head><body><button id="btnPOST">POST</button><script>$(function () {// 2. 测试POST接口let token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoi6KW_6KW_IiwiaWF0IjoxNzMzMjg5ODE3fQ.rlwgJqUEFXO4_K7FijNELqkOLnOBgGzx1GCn7QY4rXU'$('#btnPOST').on('click', function () {$.ajax({type: 'POST',url: 'http://127.0.0.1:8081/api/login_post_json',headers: {'Content-Type': 'application/json;charset=utf-8', Authorization: `Bearer ${token}` }, // 注:需要在请求头中使用Authorization字段并使用Bearer模式来发送token,data: { name: '西西', author: '11111'},success: function (res) {console.log(res)},})})})</script></body> </html>
- 安装指令
3.优缺点
优点:
- json具有通⽤性,所以可以跨语⾔
- 组成简单,字节占⽤⼩,便于传输
- 服务端⽆需保存会话信息,很容易进⾏⽔平扩展
- ⼀处⽣成,多处使⽤,可以在分布式系统中,解决单点登录问题
- 可防护CSRF攻击
缺点:
- payload部分仅仅是进⾏简单编码,所以只能⽤于存储逻辑必需的⾮敏感信息
- 需要保护好加密密钥,⼀旦泄露后果不堪设想
- 为避免token被劫持,最好使⽤https协议
3. cookie,token,session的对比
Cookie、Token和Session是Web开发中常用的三种用户会话管理机制
-
Cookie
Cookie 是一种由服务器发送到客户端浏览器的小数据片段,用于存储用户的状态信息。
它主要用于跟踪用户会话、存储用户偏好设置、记住用户登录状态等。
优点- 存储在客户端,服务器负担较轻。
- 每次请求时自动发送,适合无状态应用。
缺点
- 容量有限,单个Cookie的大小通常不超过4KB。
- 安全性较低,容易被篡改或遭受跨站请求伪造(CSRF)攻击
-
Token
Token是服务端生成的一串字符串,用作客户端进行请求的令牌。当用户第一次登录后,服务器生成一个Token并将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
优点- 无状态,适合无状态和分布式系统。
- 安全性较高,因为Token通常经过加密处理。
缺点
- 每次请求都需要验证Token,可能会增加服务器的计算负担
-
Session
Session是在服务器端存储用户会话信息的机制。当用户访问网站时,服务器会为该用户创建一个唯一的Session,并生成一个Session ID。这个Session ID用于在多个请求之间保持用户的会话状态。
优点- 存储在服务器端,安全性较高,因为数据不存储在客户端。
- 可以存储大量数据,没有容量限制。
缺点
- 占用服务器资源,可能影响性能
特性 | Cookie | Session | Token |
---|---|---|---|
存储位置 | 客户端存储 | 服务器端存储,客户端存储 Session ID | 客户端存储 |
安全性 | 易受 CSRF 攻击,易被篡改 | 更安全,敏感数据存储在服务器端 | 一旦泄露可能被盗用 |
容量 | 4KB 限制 | 服务器端可以存储更多数据 | 受限于 Token 大小,但一般较小 |
性能 | 自动随请求发送 | 服务器需要维护状态,增加负担 | 无状态机制,适合分布式应用 |
使用场景 | 适合简单的用户状态管理 | 适合需要存储大量用户数据的应用 | 适合需要无状态认证和分布式系统的应用 |
相关文章:

node.js实现分页,jwt鉴权机制,token,cookie和session的区别
文章目录 1. 分⻚功能2. jwt鉴权机制1.jwt是什么2.jwt的应用3.优缺点 3. cookie,token,session的对比 1. 分⻚功能 为什么要分页 如果数据量很⼤,⽐如⼏万条数据,放在⼀个⻚⾯显⽰的话显然不友好,这时候就需要采⽤分⻚…...

34 基于单片机的指纹打卡系统
目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52RC,采用两个按键替代指纹,一个按键按下,LCD12864显示比对成功,则 采用ULN2003驱动步进电机转动,表示开门,另一个…...
【Linux】用户操作命令
声明:以下内容均学习自《Linux就该这么学》一书 1、管理员root Linux系统的管理员之所以是root,并不是因为它的名字叫root,而是因为该用户的身份号码UID(User IDentification)的数值是0。UID相当于身份证号码&#x…...

Y20030018基于Java+Springboot+mysql+jsp+layui的家政服务系统的设计与实现 源代码 文档
家政服务系统的设计与实现 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 随着人们生活水平的提高,老龄化、少子化等多重因素影响,我国对家政服务人群的需求与日俱增。家政服务行业对我国的就业和社会效益贡献也与日俱增&#…...

windows部署PaddleSpeech详细教程
windows安装paddlespeech步骤: 1. 安装vs c编译环境 对于 Windows 系统,需要安装 Visual Studio 来完成 C 编译环境的安装。 Microsoft C Build Tools - Visual Studio 2. 安装conda conda create -y -p paddlespeech python3.8 conda activate pad…...

线程条件变量 生产者消费者模型 Linux环境 C语言实现
只能用来解决同步问题,且不能独立使用,必须配合互斥锁一起用 头文件:#include <pthread.h> 类型:pthread_cond_t PTHREAD_COND_INITIALIZER 初始化 初始化:int pthread_cond_init(pthread_cond_t * cond, NULL);…...

C++ packaged_task
packaged_task 是 C11 标准库中引入的一个模板类,它用于将可调用对象(如函数、lambda 表达式、函数对象或绑定表达式)包装起来,并允许异步地获取其结果packaged_task 类提供了一种方便的方式来创建任务,这些任务可以被…...

【联表查询】.NET开源 ORM 框架 SqlSugar 系列
.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…...

嵌入式C编程:宏定义与typedef的深入对比与应用
目录 一、宏定义(Macro Definition) 1.1. 特点与应用 1.1.1 定义常量 1.1.2 定义函数式宏 1.1.3 条件编译 1.2. 作用范围和生命周期方面 1.3. 应用注意事项 二、typedef 2.1. 特点与应用 2.1.1 简化类型声明 2.1.2 提高代码可读性 2.1.3 实现…...
高级java每日一道面试题-2024年12月03日-JVM篇-什么是Stop The World? 什么是OopMap? 什么是安全点?
如果有遗漏,评论区告诉我进行补充 面试官: 什么是Stop The World? 什么是OopMap? 什么是安全点? 我回答: 在Java虚拟机(JVM)中,Stop The World、OopMap 和 安全点 是与垃圾回收(GC)和性能优化密切相关的概念。理…...
【openGauss︱PostgreSQL】openGauss或PostgreSQL查表、索引、序列、权限、函数
【openGauss︱PostgreSQL】openGauss或PostgreSQL查表、索引、序列、权限、函数 一、openGauss查表二、openGauss查索引三、openGauss查序列四、openGauss查权限五、openGauss或PostgreSQL查函数六、PostgreSQL查表七、PostgreSQL查索引八、PostgreSQL查序列九、PostgreSQL查权…...

Dataset用load_dataset读图片和对应的caption的一个坑
代码: data_files {} if args.train_data_dir is not None:data_files["train"] os.path.join(args.train_data_dir, "**")dataset load_dataset("imagefolder",data_filesdata_files,cache_dirargs.cache_dir,) 数据࿱…...
【信息系统项目管理师】第7章:项目立项管理 考点梳理
文章目录 7.1 项目建议与立项申请7.2 项目可行性研究7.2.1 可行性研究的内容7.2.2 初步可行性研究7.2.3 详细可行性研究(重点) 7.3 项目评估与决策 【学习建议】本章大概考选择题2分左右,有可能考案例题。论文早年考过。本章知识点比较集中&a…...
知识库、提示词对大语言模型的影响测试
简介 通过对比有无知识库,测试大语言模型的回答 有无提示词对比测试 前提 大语言模型:Qwen1.5-1.8B-Chat-GPTQ-Int4 GPU:1650super,显存4G 提问:华为mate70 没有提示词 回答的内容如下 “华为mate70pro和mate40p…...
vistat-监控和分析网络状态
vistat 是一个用于监控和分析网络状态的工具,通常用于查看网络接口、流量、连接等实时数据。 原理:用户态调用系统接口获取内核中的网络统计信息。 核心功能:网络接口流量监控、查看连接状态、带宽使用分析。 使用方法: 查看接…...

EasyAnimateV5 视频生成大模型原理详解与模型使用
在数字内容创作中,视频扮演的角色日益重要。然而,创作高质量视频通常耗时且昂贵。EasyAnimate 系列旨在利用人工智能技术简化这一过程。EasyAnimateV5 建立在其前代版本的基础之上,不仅在质量上有所提升,还在多模态数据处理和跨语…...

水稻和拟南芥生命周期中单碱基分辨率的m6A定量分析-文献精读88
Quantitative profiling of m6A at single base resolution across the life cycle of rice and Arabidopsis 水稻和拟南芥生命周期中单碱基分辨率的m6A定量分析 水稻参考基因组(日本晴品种)-CSDN博客 “Xian”(籼)和“Geng”&…...

学习threejs,使用canvas更新纹理
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Texture 贴图 二、…...

【笔记2-3】ESP32 bug:PSRAM chip not found or not supported 没有外部PSRAM问题解决
主要参考b站宸芯IOT老师的视频,记录自己的笔记,老师讲的主要是linux环境,但配置过程实在太多问题,就直接用windows环境了,老师也有讲一些windows的操作,只要代码会写,操作都还好,开发…...

大数据hadoop、spark、flink、kafka发展的过程
将sql 代发翻译成java 程序 将python 程序通过pyspark框架翻译成java 程序,然后运行在spark计算框架上...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...