You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express项目server.js问题:未登录访问/home需重定向至登录页

问题分析与解决方案

你的代码存在几个核心问题导致需求无法实现:

  1. 没有使用会话(Session)跟踪用户登录状态,req.isAuthenticated()是Passport.js专属方法,但你并未引入Passport,该方法实际不存在。
  2. 缺少验证用户是否已登录的中间件,无法保护/home路径。
  3. 静态文件配置可能导致受保护页面被直接访问,绕过路由验证。

以下是修改后的完整代码及关键说明:

修改后的代码

const express = require('express');
const sqlite3 = require('sqlite3').verbose();
const session = require('express-session'); // 新增:引入会话管理模块

const app = express();
const port = 3000;

// 新增:配置会话(生产环境需替换secret为安全密钥,HTTPS环境下将secure设为true)
app.use(session({
  secret: 'library-secret-key-123',
  resave: false,
  saveUninitialized: false,
  cookie: { secure: false, maxAge: 3600000 } // cookie有效期1小时
}));

// Open SQLite database connection
const db = new sqlite3.Database('mydatabase.db', (err) => {
  if (err) {
    console.error(err.message);
  } else {
    console.log('Connected to the database.');
  }
});

// 调整:静态文件目录改为public,存放无需保护的资源(如css、js)
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));

// 修改:检查用户是否未登录(用于保护登录页)
function checkNotAuthenticated(req, res, next) {
  if (req.session.user) {
    return res.redirect('/home');
  }
  next();
}

// 新增:检查用户是否已登录(用于保护/home路径)
function checkAuthenticated(req, res, next) {
  if (req.session.user) {
    return next();
  }
  res.redirect('/');
}

// 登录页路由(仅未登录用户可访问)
app.get('/', checkNotAuthenticated, (req, res) => {
  res.sendFile(__dirname + '/views/login.html');
});

// 登录验证接口
app.post('/login', checkNotAuthenticated, (req, res) => {
  const username = req.body.username;
  const password = req.body.password;

  db.get('SELECT * FROM users WHERE username = ? AND password = ?', [username, password], (err, row) => {
    if (err) {
      console.error(err.message);
      return res.sendStatus(500);
    }

    if (row) {
      // 新增:登录成功后将用户信息存入会话
      req.session.user = { id: row.id, username: row.username };
      res.redirect('/home');
    } else {
      // 优化:登录失败返回登录页并携带错误标记
      res.redirect('/?error=invalid');
    }
  });
});

// 受保护的首页路由(仅已登录用户可访问)
app.get('/home', checkAuthenticated, (req, res) => {
  res.sendFile(__dirname + '/views/home.html'); // 对应你的首页文件
});

// 可选:登出接口
app.post('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) return res.sendStatus(500);
    res.redirect('/');
  });
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

关键修改点说明

  • 引入express-session:通过会话存储用户登录状态,让服务器能识别已登录用户。
  • 新增checkAuthenticated中间件:检查会话中是否存在用户信息,若不存在则直接重定向到登录页,实现你需要的路径保护逻辑。
  • 修复checkNotAuthenticated中间件:替换无效的req.isAuthenticated(),改用会话信息判断,阻止已登录用户重复访问登录页。
  • 调整静态文件目录:将无需保护的资源放在public目录,受保护页面通过路由返回,避免静态文件直接访问绕过验证。
  • 登录成功写入会话:验证通过后将用户关键信息存入会话,后续请求可通过req.session.user判断登录状态。

额外优化建议

  1. 密码加密存储:当前代码明文存储密码,风险极高,建议使用bcrypt库对密码哈希后再存入数据库。
  2. 错误提示优化:在登录页读取error参数,显示“用户名或密码错误”的提示信息。
  3. 生产环境配置:将会话secret改为随机生成的安全密钥,HTTPS环境下开启cookie.secure,提升安全性。

内容的提问来源于stack exchange,提问作者gugaboii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:59:51