Express项目server.js问题:未登录访问/home需重定向至登录页
问题分析与解决方案
你的代码存在几个核心问题导致需求无法实现:
- 没有使用会话(Session)跟踪用户登录状态,
req.isAuthenticated()是Passport.js专属方法,但你并未引入Passport,该方法实际不存在。 - 缺少验证用户是否已登录的中间件,无法保护
/home路径。 - 静态文件配置可能导致受保护页面被直接访问,绕过路由验证。
以下是修改后的完整代码及关键说明:
修改后的代码
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判断登录状态。
额外优化建议
- 密码加密存储:当前代码明文存储密码,风险极高,建议使用
bcrypt库对密码哈希后再存入数据库。 - 错误提示优化:在登录页读取
error参数,显示“用户名或密码错误”的提示信息。 - 生产环境配置:将会话
secret改为随机生成的安全密钥,HTTPS环境下开启cookie.secure,提升安全性。
内容的提问来源于stack exchange,提问作者gugaboii
相关产品推荐
相关产品推荐

