node前后端分离(node.js中,登录状态30分钟过期,怎么做?)

node前后端分离(node.js中,登录状态30分钟过期,怎么做?)
node.js中,登录状态30分钟过期,怎么做?

在 Node.js 中实现登录状态 30 分钟过期,核心思路是基于 Token(推荐 JWT)或 Session 设置过期时间,并配合前端无感刷新或后端主动校验来确保时效性。以下是两种主流方案(JWT 方案更适合前后端分离场景),均完整可运行。

方案一:JWT(推荐,前后端分离首选)

JWT(JSON Web Token)是无状态令牌,可直接在令牌中设置过期时间,后端校验时自动判断是否失效。

实现步骤 & 完整代码

  1. 安装依赖

bash

运行

npm install jsonwebtoken express cookie-parser
  1. 核心代码(Express 示例)

javascript

运行

const express = require('express');const jwt = require('jsonwebtoken');const cookieParser = require('cookie-parser');const app = express();// 中间件app.use(express.json());app.use(cookieParser());// 密钥(生产环境请用环境变量,不要硬编码)const SECRET_KEY = 'your-secret-key-123456';// 过期时间:30分钟(单位:秒)const EXPIRES_IN = 30 * 60;// 1. 登录接口:生成JWT并返回(存入cookie更安全)app.post('/login', (req, res) => {  // 模拟用户校验(实际需查数据库)  const { username, password } = req.body;  if (username === 'admin' && password === '123456') {    // 生成JWT,设置30分钟过期    const token = jwt.sign(      { userId: 1, username: 'admin' }, // 自定义载荷(不要存敏感信息)      SECRET_KEY,      { expiresIn: EXPIRES_IN } // 过期时间:30分钟    );    // 将token存入cookie(httpOnly防止前端JS窃取,secure生产环境开启https)    res.cookie('token', token, {      httpOnly: true,      maxAge: EXPIRES_IN * 1000, // cookie过期时间(毫秒),与JWT一致      // secure: true, // 生产环境开启      sameSite: 'strict' // 防止CSRF    });    return res.json({ code: 200, msg: '登录成功' });  }  res.json({ code: 401, msg: '账号或密码错误' });});// 2. 登录状态校验中间件(所有需要登录的接口都需经过此中间件)const authMiddleware = (req, res, next) => {  try {    // 从cookie获取token(也可从header的Authorization获取)    const token = req.cookies.token || req.headers.authorization?.split(' ')[1];    if (!token) {      return res.json({ code: 401, msg: '未登录' });    }    // 校验token(自动验证过期时间,过期会抛错)    const decoded = jwt.verify(token, SECRET_KEY);    req.user = decoded; // 将用户信息挂载到req,供后续接口使用    next();  } catch (err) {    // token过期或无效    if (err.name === 'TokenExpiredError') {      return res.json({ code: 401, msg: '登录状态已过期,请重新登录' });    }    return res.json({ code: 401, msg: '登录状态无效' });  }};// 3. 需要登录的示例接口app.get('/user/info', authMiddleware, (req, res) => {  res.json({    code: 200,    data: {      userId: req.user.userId,      username: req.user.username    }  });});// 4. 退出登录(清除cookie)app.post('/logout', (req, res) => {  res.clearCookie('token');  res.json({ code: 200, msg: '退出成功' });});app.listen(3000, () => {  console.log('服务启动:http://localhost:3000');});

关键说明

  • expiresIn: 30 * 60:JWT 令牌本身设置 30 分钟过期,jwt.verify 会自动校验过期时间。
  • cookie.maxAge:Cookie 的过期时间与 JWT 保持一致,前端无法修改,更安全。
  • TokenExpiredError:捕获 token 过期异常,明确提示用户重新登录。

方案二:Session(传统服务端会话)

Session 是服务端存储的会话,通过设置 Session 过期时间实现 30 分钟失效,适合服务端渲染场景。

实现步骤 & 完整代码

  1. 安装依赖

bash

运行

node前后端分离(node.js中,登录状态30分钟过期,怎么做?)

npm install express express-session
  1. 核心代码

javascript

运行

const express = require('express');const session = require('express-session');const app = express();app.use(express.json());// 配置Session(生产环境需用redis存储,避免内存泄漏)app.use(session({  secret: 'your-session-secret', // 加密密钥  resave: false, // 不强制重新保存未修改的session  saveUninitialized: false, // 不保存未初始化的session  cookie: {    maxAge: 30 * 60 * 1000, // Session的cookie过期时间:30分钟(毫秒)    httpOnly: true,    // secure: true // 生产环境开启https  },  // 生产环境推荐:使用redis存储session  // store: new RedisStore({ client: redisClient })}));// 1. 登录接口:设置Sessionapp.post('/login', (req, res) => {  const { username, password } = req.body;  if (username === 'admin' && password === '123456') {    // 存储用户信息到Session    req.session.user = { userId: 1, username: 'admin' };    // 手动刷新Session过期时间(可选,默认cookie.maxAge会自动倒计时)    req.session.cookie.maxAge = 30 * 60 * 1000;    return res.json({ code: 200, msg: '登录成功' });  }  res.json({ code: 401, msg: '账号或密码错误' });});// 2. 登录校验中间件const authMiddleware = (req, res, next) => {  if (!req.session.user) {    return res.json({ code: 401, msg: '登录状态已过期或未登录' });  }  // 每次请求刷新过期时间(可选,实现“活跃则续期”)  req.session.cookie.maxAge = 30 * 60 * 1000;  next();};// 3. 示例接口app.get('/user/info', authMiddleware, (req, res) => {  res.json({    code: 200,    data: req.session.user  });});// 4. 退出登录:销毁Sessionapp.post('/logout', (req, res) => {  req.session.destroy((err) => {    if (err) return res.json({ code: 500, msg: '退出失败' });    res.json({ code: 200, msg: '退出成功' });  });});app.listen(3000, () => {  console.log('服务启动:http://localhost:3000');});

关键说明

  • cookie.maxAge: 30 * 60 * 1000:Session 的 Cookie 过期时间设为 30 分钟,服务端会自动清理过期 Session。
  • 可选优化:每次用户活跃(请求接口)时刷新 req.session.cookie.maxAge,实现 “30 分钟无操作才过期”(更符合实际需求)。
  • 生产环境:必须用 Redis 等存储 Session(express-session 默认内存存储,重启服务会丢失,且内存泄漏风险高)。

进阶优化(可选)

  1. 无感刷新 Token:给 JWT 增加 “刷新令牌”(refreshToken),过期时间设为 7 天,当 accessToken(30 分钟)过期时,前端用 refreshToken 静默刷新新的 accessToken,避免用户频繁登录。
  2. Redis 存储黑名单:JWT 是无状态的,退出登录后需手动将 Token 加入 Redis 黑名单,校验时先查黑名单再验过期。
  3. 前端主动处理:前端存储 Token 过期时间,提前 5 分钟提示用户 “登录即将过期”,或自动触发刷新。

总结

  1. JWT 方案:无状态、适合前后端分离,核心是 jwt.sign 时设置 expiresIn: 30*60,校验时捕获 TokenExpiredError。
  2. Session 方案:服务端存储、适合传统项目,核心是 session.cookie.maxAge = 30*60*1000,可选活跃续期。
  3. 生产环境:JWT 需配合 Redis 黑名单,Session 需用 Redis 存储,且密钥 / 敏感配置要放在环境变量中。

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有