基于用户认证的Login/Logout按钮显隐异常求助(MySQL+EJS)
问题:登录后导航栏按钮状态不更新
使用MySQL+EJS开发时,登录成功后Login/Register按钮仍显示,Logout按钮无法正常展示,需实现登录状态切换按钮显示的功能。
问题根源及修复步骤
1. 缺失bcrypt依赖与导入
登录逻辑中使用了bcrypt.compare验证密码,但未安装依赖也未导入模块,导致登录流程直接报错,无法设置登录状态。
- 安装bcrypt:
npm install bcrypt
- 在
server.js顶部添加导入:
const bcrypt = require('bcrypt');
2. 用户查询结果判断逻辑错误
MySQL查询无匹配用户时返回空数组而非null,原代码!result的判断无法识别无用户的情况,导致密码验证逻辑错误。
修复后的登录路由代码:
app.post('/login', async(req, res) => { try { const { username, password } = req.body; const result = await query('SELECT * from users WHERE username = ?', [username]); // 判断是否查询到用户 if (result.length === 0) { return res.status(401).send('用户名不存在'); } // 验证密码 const isPasswordValid = await bcrypt.compare(password, result[0].password); if (!isPasswordValid) { return res.status(401).send('密码错误'); } // 设置登录状态到session req.session.userId = result[0].userId; // 用userId避免和session自身id冲突 req.session.loggedin = true; req.flash('success', '欢迎回来!'); res.redirect('/'); // 重定向到首页,确保导航栏读取最新session } catch (error) { console.error(error); req.flash('error', '登录失败'); res.redirect('/login'); } });
3. 导航栏EJS判断逻辑优化
原判断未处理session未初始化的情况,添加可选链操作符避免报错,简化判断逻辑:
修改navbar.ejs中的按钮判断部分:
<div class="navbar-nav ml-auto"> <% if(!session?.loggedin) { %> <a class="nav-link" href="/login">Login</a> <a class="nav-link" href="/register">Register</a> <% } else { %> <a class="nav-link" href="/logout">Logout</a> <% } %> </div>
4. 额外注意事项
- 确保用户表中存储的密码是通过
bcrypt.hash生成的哈希值,而非明文,否则密码验证会失败。 - 可在全局中间件中添加
console.log(req.session),查看登录后session是否正确写入loggedin状态。
完成以上修复后,登录成功时session会记录登录状态,导航栏自动切换为Logout按钮;退出登录时session.destroy()清除状态,导航栏恢复显示Login/Register按钮。
内容的提问来源于stack exchange,提问作者Cristian
相关产品推荐
相关产品推荐

