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

Node.js+EJS项目实现登录后导航栏从登录切换为注销功能求助

解决方案:基于Session实现登录状态的导航栏切换

要实现登录后切换导航栏按钮的功能,核心是跟踪用户的登录状态——你现在的代码里没有会话管理,所以服务器不知道用户是否已经登录。我们可以用express-session来实现这一点,下面是分步实现:

步骤1:安装并配置Session中间件

首先安装express-session包:

npm install express-session

然后在你的app.js里引入并配置它(放在mongoose连接之后,路由之前):

const session = require('express-session');

// 配置Session
app.use(session({
  secret: 'your-own-secret-key-keep-it-safe', // 换成你自己的随机密钥,生产环境要保密
  resave: false,
  saveUninitialized: false,
  cookie: {
    maxAge: 24 * 60 * 60 * 1000 // 会话有效期1天,可根据需求调整
  }
}));

步骤2:修改登录/注册路由,设置Session状态

当用户登录或注册成功时,我们要在Session里标记用户已登录:

登录路由修改

app.post("/login", function (req, res) {
  const username = req.body.username;
  const password = req.body.password;
  const role = "admin";

  User.findOne({ email: username }, function (err, foundUser) {
    if (err) {
      console.log(err);
      return res.redirect('/login'); // 出错时重定向回登录页
    }
    if (!foundUser) {
      // 用户不存在,重定向回登录页
      return res.redirect('/login');
    }
    // 验证密码(注意:生产环境一定要用bcrypt哈希密码!这里只是基础实现)
    if (foundUser.password === password) {
      // 设置Session标记登录状态
      req.session.isLoggedIn = true;
      req.session.user = foundUser; // 可选:保存用户信息到Session

      // 根据角色跳转对应页面,同时传递登录状态给模板
      if (foundUser.role === role) {
        res.render("adminportal", { isLoggedIn: req.session.isLoggedIn })
      } else {
        res.render("portal", { isLoggedIn: req.session.isLoggedIn })
      }
    } else {
      // 密码错误,重定向回登录页
      res.redirect('/login');
    }
  })
});

注册路由修改(注册成功自动登录)

app.post("/register", function (req, res) {
  const newUser = new User({
    firstname: req.body.firstname,
    lastname: req.body.lastname,
    email: req.body.username,
    password: req.body.password,
    conpassword: req.body.conpassword,
    role: "user" // 可以给新用户默认设置user角色
  });

  newUser.save(function (err) {
    if (err) {
      console.log(err);
      return res.redirect('/register');
    }
    // 注册成功后自动登录,设置Session
    req.session.isLoggedIn = true;
    req.session.user = newUser;
    res.render("portal", { isLoggedIn: req.session.isLoggedIn })
  });
});

注销路由修改(销毁Session)

app.get("/logout", (req, res) => {
  // 销毁Session,清除登录状态
  req.session.destroy(err => {
    if (err) console.log(err);
    res.redirect("/");
  });
});

步骤3:给所有页面模板传递登录状态

修改所有渲染页面的路由,把isLoggedIn状态传给EJS模板,这样导航栏就能根据状态判断显示内容:

// 首页
app.get("/", function (req, res) {
  res.render("main", { isLoggedIn: req.session.isLoggedIn });
});

// 登录页
app.get("/login", function (req, res) {
  res.render("login", { isLoggedIn: req.session.isLoggedIn });
});

// 注册页
app.get("/register", function (req, res) {
  res.render("register", { isLoggedIn: req.session.isLoggedIn });
});

步骤4:修改Navbar.ejs,添加条件渲染

用EJS的if/else语法,根据isLoggedIn状态切换显示的按钮:

<ul class="navbar-nav">
  <% if (isLoggedIn) { %>
    <!-- 已登录时显示注销按钮 -->
    <li class="nav-item navbar-distance">
      <a class="nav-link " href="/logout">Logout</a>
    </li>
  <% } else { %>
    <!-- 未登录时显示登录和注册按钮 -->
    <li class="nav-item navbar-distance">
      <a class="nav-link " href="/login">Sign in</a>
    </li>
    <li class="nav-item navbar-distance">
      <a class="nav-link nav-border-with" href="/register">Register</a>
    </li>
  <% } %>
  <!-- "Talk to Us" 始终显示 -->
  <li class="nav-item navbar-distance">
    <a class="nav-link nav-border-without" href="#contacts">Talk to Us</a>
  </li>
</ul>

重要提醒

  1. 密码安全:你现在的代码直接存储明文密码,生产环境一定要用bcrypt等工具哈希密码后再存储,避免数据泄露风险。
  2. Session持久化:当前配置用的是内存存储Session,服务器重启后所有会话会丢失。生产环境可以用connect-mongo把Session存在MongoDB里。
  3. Secret密钥:session配置里的secret要换成随机的安全字符串,不要用示例中的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 16:19:09