前端保存登录信息-jwt的使用

node+express开发中,经常会使用后端session+前端cookie方式来保存登录信息,如果后端采用多服务器的话,session要共享还得采用redis来保存session。而session多少还是有一些存储和计算开销的;另外前端,用cookie来存放sessionid或者其他一些登录信息,而一些禁用了cookie的场景,或者一些本身就不是浏览器的应用的话,在cookie中保存登录信息就不太适用了。

这种情况下,可以考虑采用jwt存本地存储方式来对应。

以下给出一个简单的例子。

通过nginx反向代理发布,nginx.conf里相关配置是这样的:

lua 复制代码
        location /app/ {
            proxy_pass    http://jwtdemo.dgiij.org:3000/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
	        }

后端服务js

javascript 复制代码
const express = require('express')
const app = express()
const jwt = require('jsonwebtoken')
var { expressjwt: ejwt }  = require('express-jwt')
const jwtSecretKey= 'ParisOlympics2024';
const jwtexpiresIn= '12h'
const app_prefix="https://jwtdemo.dgiij.org/app"
const loginurl="https://jwtdemo.dgiij.org/app/login.html&redurl="
var localusers = require("./localusers.json");

app.use("/", express.static("html/app"));
app.use("/pub", express.static("html/pub"));

app.use(ejwt({ secret: jwtSecretKey, algorithms: ["HS256"]}).unless({ path: [/^\/login/,/^\/pub/,/^\/index/] }))

app.use(function (err, req, res, next) {
	if (err.name === 'UnauthorizedError') {
		let redurl=app_prefix+ req.originalUrl;  
		res.redirect(loginurl+redurl);
		}
})

app.post('/login',express.json(), (req, res) => {
	let obj=req.body;
	let matchuser=localusers.find(item=>((item.userid==obj.uid)&&(item.password==obj.upw)));
	if (matchuser!=undefined) { 
		let clientip=req.header("x-forwarded-for")?req.header("x-forwarded-for"):req.ip;
		let userinfo={"userid":matchuser.userid,"username":matchuser.username,"login_ip":clientip}
		let token = jwt.sign(userinfo, jwtSecretKey, { expiresIn: jwtexpiresIn})
		res.json({ "code": 200, "jwt": token })
		}
	else { res.json({ "code": 401, "msg": '登录失败' }) }
})
 
app.get('/getuserinfo', (req, res) => {
	res.json({ "code": 200, userinfo: req.auth })
})

app.listen(3000, console.log('server is running on port 3000'))

前端登录页面(html/app/login.html):

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>jwt demo login</title>
<script src="pub/axios.min.js"></script>
<script src="pub/jquery-3.6.1.min.js"></script>
</head>

<body>
	<input type="text" id="uid" name="uid" placeholder="用户名">
	<input type="password" id="upw" name="upw" placeholder="密码">
	<button>账号密码登录</button>
</body>
<script>
let reg = new RegExp("(^|&)" + "redurl" + "=([^&]*)(&|$)","i");
var redurl = location.search.substr(1).match(reg);

$("#login").click(()=>{ 
	if ((document.getElementById("uid").value.trim()=="")||(document.getElementById("upw").value.trim()=="")) { alert("请输入用户名和密码!"); }
	else {
		let nuid=document.getElementById("uid").value.trim().toLowerCase();
		axios.post("/app/login",{"uid": nuid,"upw": document.getElementById("upw").value.trim()}).then(resp=>{
			let obj=resp.data;
			if (obj.code==200) {
				localStorage.setItem("jwt", obj.jwt);
				document.location=((redurl==null)?"/app/index.html":redurl[2]);
				}
			else { alert(obj.msg); }
			}).catch(errp2 => { console.log(errp2); alert("app服务错"); });
		}
	});

</script>
</html>

前端app页面(html/app/index.html):

html 复制代码
<!DOCTYPE html>
<html lang="en">
 
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jwt demo app</title>
<script src="pub/axios.min.js"></script>
<script src="pub/jquery-3.6.1.min.js"></script>
</head>
 
<body>
<span>&nbsp;&nbsp;当前会话用户:</span>
<span name="loginname" id="loginname"></span>
<br>
<br>

</body>
<script>
	axios.defaults.headers.common['Authorization'] ='Bearer ' + localStorage.getItem('jwt');
	axios.get("/app/getuserinfo").then(res=>{
		let obj=res.data;
		document.getElementById("loginname").innerHTML = obj.userinfo.username ;
		}).catch(errp => { console.log(errp); alert("app服务错,请稍后再刷新页面"); });
</script>
</html>
相关推荐
LaughingZhu5 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫5 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
Mahir085 小时前
Spring 循环依赖深度解密:从问题本质到三级缓存源码级解析
java·后端·spring·缓存·面试·循环依赖·三级缓存
小鹏linux6 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水7 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger7 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)7 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态7 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态7 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart8 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter