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

passport.js登出后无法结束会话 退出后仍可访问/profile路由

问题排查记录

项目依赖版本

"express": "^4.18.1",
"express-session": "^1.17.3",
"mongoose": "^6.4.0",
"mongoose-encryption": "^2.1.2",
"passport": "^0.6.0",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^7.1.2"

app.js核心配置代码

require("dotenv").config();
const express = require("express");
const ejs = require("ejs");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");

const app = express();
app.use(express.static("public"));
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));

app.use(
  session({
    secret: process.env.SECRET,
    resave: false,
    saveUninitialized: true,
    cookie: { secure: true },
  })
);

app.use(passport.initialize());
app.use(passport.session());

mongoose.connect("mongodb://localhost:27017/userDB", { useNewUrlParser: true });

const userSchema = new mongoose.Schema({
  email: String,
  password: String
});

userSchema.plugin(passportLocalMongoose);
const User = new mongoose.model("User", userSchema);

passport.use(User.createStrategy());

passport.serializeUser(function (user, done) {
  done(null, user.id);
});

passport.deserializeUser(function (id, done) {
  User.findById(id, function (err, user) {
    done(err, user);
  });
});

app.get("/profile", function (req, res) {
  User.find({ email: { $ne: null } }, function (err, foundUsers) {
    if (err) {
      console.log(err);
    } else {
      if (foundUsers) {
        res.render("profile", { foundUsersEjs: foundUsers });
      }
    }
  });
});

已尝试的登出逻辑

  • 方法一
app.post("/logout", function (req, res) {
  req.logout(function (err) {
    if (err) {
      console.log(err);
    } else {
      req.session.destroy(function (err) {
        res.redirect("/");
      });
    }
  });
});
  • 方法二
app.post("/logout", function (req, res) {
  req.session.destroy(function (err) {
    if (err) {
      console.log(err);
    } else {
      req.logout(function (err) {
        res.redirect("/");
      });
    }
  });
});

前端登出按钮代码

<form action="/logout" method="post">
    <button class="btn btn-light btn-lg">Log Out</button>
</form>

问题现象

在http://localhost:4100/profile页面点击登出按钮后,页面会正常跳转至首页/,但手动在地址栏输入/profile路径时,仍然可以直接访问profile页面内容,未做登录拦截。


问题诱因

问题由多个配置错误共同导致:

  1. 路由缺少登录鉴权逻辑:当前/profile路由没有任何登录状态校验,不管用户是否登录,只要发起请求就会直接查询数据库返回页面内容,这是未登录状态下仍能访问profile页的直接原因。
  2. Session Cookie配置不符合本地开发环境:session配置中写死了cookie: { secure: true },该属性要求浏览器仅在HTTPS协议下才会携带、持久化session cookie。本地开发用的是HTTP协议,会导致session状态无法正常在客户端留存,登出、登录状态校验相关逻辑的实际执行效果不符合预期。
  3. 方法二的登出逻辑顺序错误:req.logout()是passport提供的清除请求上用户挂载信息的方法,需要在session销毁前执行,先销毁session再调用logout没有实际意义。
修复方案
  1. 给受保护路由加鉴权校验
    对需要登录才能访问的路由,统一加登录状态判断,可抽成公共中间件复用:
function isAuth(req, res, next) {
  if (req.isAuthenticated()) return next();
  res.redirect("/login"); // 未登录直接跳登录页
}

// 路由注册时挂载中间件
app.get("/profile", isAuth, function (req, res) {
  User.find({ email: { $ne: null } }, function (err, foundUsers) {
    if (err) {
      console.log(err);
    } else {
      if (foundUsers) {
        res.render("profile", { foundUsersEjs: foundUsers });
      }
    }
  });
});
  1. 修正Session Cookie配置
    根据运行环境动态适配secure属性,本地开发环境关闭secure限制:
app.use(
  session({
    secret: process.env.SECRET,
    resave: false,
    saveUninitialized: false, // 调整为false,不存储未初始化的无效会话
    cookie: { 
      secure: process.env.NODE_ENV === "production", // 生产环境HTTPS下开启true,本地开发为false
      maxAge: 1000 * 60 * 60 * 24 // 可按需设置cookie过期时间
    },
  })
);
  1. 使用标准登出逻辑
    按先清除passport登录态、再销毁session、最后清除客户端残留cookie的顺序编写:
app.post("/logout", function (req, res, next) {
  req.logout(function (err) {
    if (err) return next(err);
    req.session.destroy(function (err) {
      if (err) return next(err);
      res.clearCookie("connect.sid"); // 清除express-session默认的客户端cookie
      res.redirect("/");
    });
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:21:31