node 之 身份认证(cookie,session,token<jwt>)
对于服务端渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:
.服务端渲染推荐使用 Session 认证机制 (SessIon也会用到cookie)
前后端分离推荐使用 jwt 认证机制
cookie (保存在浏览器上)
简单案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | //导入模块const express = require("express"); const path = require( "path" ); const cookieParser = require( "cookie-parser" ); //创建服务 const app = express(); app.listen( "8001" , () => { console.log( "服务已开启" ); }); // 应用级配置使用cookie-parser app.use(cookieParser()); //应用级配置 app.use(express.urlencoded({ extended: false })); //登录页面 app. get ( "/login.html" , (req, res) => { res.sendFile(path. join (__dirname, "public" , "login.html" )); }); //登录提交的接口 app.post( "/api/login" , (req, res) => { if (req.body.username === "admin" && req.body.password === "123" ) { res.cookie( "isLogin" , 1, { maxAge: 2 * 1000 }); res.send(`<script>alert( '登录成功' );location.href= "/index.html" ;</script>`); } else { res.send(`<script>alert( '登录失败' );location.href= "/login.html" ;</script>`); } }); //后台首页 app. get ( "/index.html" , (req, res) => { if (req.cookies && req.cookies.isLogin === "1" ) { res.sendFile(path. join (__dirname, "public" , "index.html" )); } else { res.send(`<script>alert( '登录失败' );location.href= "/login.html" ;</script>`); } }); |
有效期
默认:浏览会话结束(也就是关闭浏览器)
设置有效期:res.cookie('isLogin',1,{maxAge:毫秒数})
优缺点:
优点:
体积小
客户端存放,不占用服务器空间
浏览器会自动携带,不需要写额外的代码,比较方便
缺点
客户端保存,安全性较低,但是可以存放加密的字符窜来解决
可以实现跨域,但是难度大,难理解,代码难度高
不适合前后端分离的开发
适用场景
传统的服务器渲染模式
存储安全性较低的数据,比如视频的存放位置等
session (保存在服务器上)
简单案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | //导入模块<br>const express = require("express"); const path = require( "path" ); // const cookieParser = require("cookie-parser"); const session = require( "express-session" ); const app = express(); app.listen( "8001" , () => { console.log( "服务已开启" ); }); // 应用级配置使用cookie-parser // app.use(cookieParser()); //应用级配置 app.use(express.urlencoded({ extended: false })); app.use( session({ secret: "123" , //这个随便写,第二次进行加密 saveUninitialized: false , resave: false , }) ); //登录页面 app. get ( "/login.html" , (req, res) => { res.sendFile(path. join (__dirname, "public" , "login.html" )); }); //登录提交的接口 app.post( "/api/login" , (req, res) => { console.log(req.body); if (req.body.username === "admin" && req.body.password === "123" ) { // res.cookie("isLogin", 1, { maxAge: 2 * 1000 }); req.session.isLogin = 1; res.send(`<script>alert( '登录成功' );location.href= "/index.html" ;</script>`); } else { res.send(`<script>alert( '登录失败' );location.href= "/login.html" ;</script>`); } }); //后台首页 app. get ( "/index.html" , (req, res) => { if (req.session && req.session.isLogin === 1) { console.log( "这个session是有数据的" ); } // if (req.cookies && req.cookies.isLogin === "1") { // res.sendFile(path.join(__dirname, "public", "index.html")); // } else { // res.send(`<script>alert('登录失败');location.href="/login.html";</script>`); // } }); |
有效期
默认:浏览会话结束(也就是关闭浏览器)
优缺点:
优点:
服务端存放,安全性高
浏览器会自动携带cookie,不需要写额外的代码,比较方便
适合服务器端渲染模式
缺点
占用服务器端空间
session实现离不开cookie,如果禁用cookie,session不好实现
不适合前后端分离的开发
适用场景
传统的服务器渲染模式
安全性要求比较高的数据可以使用session存放,比如用户私密信息,验证码等
JWT(token) json web token
注意:数据持久化 : localStorage 可以存储 token
原理分析
1.前端提交用户名和密码,服务端验证
2.服务端验证通过,生成token,返回给前端
3.前端自行保存token(localstorage)
4.登录成功后,每次请求要在请求头带上Authorization,只是token
简单案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | //express-jwt 模块用于解密 'token' 字符串 //规范:解密token, //1.unless:如果没有unless方法,则默认所有接口都需要验证,unless把不要验证的接口排除掉 //2.secret:加密秘钥 //3.algorithms:加密算法 ['HS256'] //4.path 取值范围, //---字符串表示排除一个地址,如'/api/login' //---数组:表示排除多个地址,如['/api/login',''] //---正则:表示排除符合规则的地址,如/^\/api/(排除以/api开头的接口) //jsonwebtoken 模块用于加密 , 还可以控制哪些接口需要身份认证 //规范: //1.token:'bearer '+jwt.sign(要保存的信息,秘钥,配置项) //2.expiresIn 值是字符串时为毫秒,值是数字时为秒 //导入模块 const express = require( "express" ); const jwt = require( "jsonwebtoken" ); const expressJWT = require( "express-jwt" ); //创建服务 const app = express(); app.listen( "8001" , () => { console.log( "服务已经开启" ); }); //应用级配置 app.use(express.urlencoded({ extended: false })); //用于token验证应用级配置 app.use( expressJWT({ secret: "bigevent-970" , algorithms: [ "HS256" ], }).unless({ path: /^\/api/ }) ); //请求 app.post( "/api/login" , (req, res) => { console.log(req.body); if (req.body.username === "admin" && req.body.password === "123" ) { res.json({ status: 0, msg: "登录成功" , token: "bearer " + jwt.sign({ username: "admin" , age: 20 }, "bigevent-970" , { expiresIn: 20, }), }); } else { res.json({ status: 1, msg: "登录失败" , }); } }); //用去用户信息 app. get ( "/my/getUser" , (req, res) => { res.json({ status: 0, msg: "获取信息成功" , data: { name: "admin" , age: 18, }, }); }); |
优缺点:
优点:
token由客户端保存,不会占用服务器空间
缺点
客户端发送请求的时候,需要手动编写代码,携带token
适用场景
适合前后端分离的开发模式
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现