Passport js“isAuthenticated()”无法按预期工作。但它确实适用于邮递员

问题描述 投票:0回答:1

因此,我有一个简单的 Node Express 服务器,并且正在使用 Passport.js 处理身份验证。当我试图让它正常工作时我很挣扎。

设置如下:

  • 我有一个 React 前端,用户可以在表单中输入他们的电子邮件和密码。 (不应该是问题,因为我尝试从 html 和脚本文件发出相同的 POST 请求,得到了相同的错误)。

  • 提交表单后,应用程序应使用电子邮件和密码数据向服务器(http://localhost:8080/login)发送 POST 请求。

  • 前端应用程序使用Axios向后端发送POST请求。 (尝试获取,相同的响应)。

  • 服务器应该:

    • 接收电子邮件和密码。

    • 验证这些凭据是否正常。

    • 序列化/反序列化用户。

    • 重定向到受 PassportAuth 中间件保护的“/auth/jwt”。 (“/auth/jwt”尚未实现,因此该路由仅获取 de req 并发送 200 状态,它不执行任何其他操作)。

    • 问题仍然存在。在 PassportAuth 中间件中,本质上是“req.isAuthenticated()”,返回 false 除非我从邮递员发送电子邮件和密码,这使得一切都非常令人沮丧。

    • 会话存储在 MongoDB 中,并且密钥“passport”确实与用户的 _id 一起存在,如预期的那样,但我不知道为什么它不起作用。

  • 我的想法:

    • 应该不是cors问题,因为我设置了app.use(cors())。

    • 客户要求应该没问题。

    • 网络应用程序和邮递员的请求是相同的,只是电子邮件和密码。

    • 标题问题?尝试了不同的配置,仍然不起作用。

反应前端:

...
const userData = { email, password };
const config = { headers: { "content-type": "application/json" }};
const res = await axios.post("http://localhost:8080/login", userData, config);
console.log(res);
...

服务器.js

const initializePassport = require("./passport/local");

const sessionConfig = {
    secret: SESSION_SECRET,
    resave: false,
    saveUninitialized: false, // Resave and saveUninitialized: tried false and true.
    cookie: {
      secure: false,
      httpOnly: false,
    },

    store: new mongoStore({
      mongoUrl: URI_CLOUD_CONNECTION,
      ttl: 60 * 30,
      expires: 60 * 30,
      autoRemove: "native",
    }),
  }

  try {
    await mongoose.connect(URI_CLOUD_CONNECTION);

    initializePassport(passport); // local.js
    app.use(express.json());
    app.use(express.urlencoded({ extended: true }));
    app.use(cookieParser(SESSION_SECRET));
    app.use(cors());
    app.use(expressSession(sessionConfig)); // express-session

    // Passport initialization
    app.use(passport.initialize());
    app.use(passport.session());

登录途径:

// "/login"
router.route("/").post(PassportController.login);

护照控制器:

const passport = require("passport");

const login = passport.authenticate("login", {
  successRedirect: "/auth/jwt",
})

“/auth/jwt”路线:

const passportAuth = require("../../middlewares/passportAuth");
const JwtController = require("../../controllers/authControllers/jwt-controller");

// "/auth/jwt"
router.get("/", passportAuth, JwtController.generateTokenAndRedirect); // This JwtController just sends status 200.

PassportAuth 中间件:

module.exports = (req, res, next) => {
  if (!req.isAuthenticated()) {
    logger.error("User not authenticated by passport!");
    return res.sendStatus(401);
  }

  console.log("Passport ID en session: ", req.session.passport);
  logger.info("PassportAuth authenticated.");

  next();
};

Local.js(护照主要逻辑):

const LocalStrategy = require("passport-local").Strategy;

module.exports = (passport) => {
  const authenticateUser = async (req, email, password, done) => {
    try {
      const user = await userModel.getUserByEmail(email);

      if (!user) {
        const errorMessage = { message: "Requested user does not exist." };
        return done(errorMessage, false);
      }

      const isPasswordValid = await userModel.isPasswordValid(email, password);

      if (!isPasswordValid) {
        const errorMessage = { message: "Wrong password." };
        return done(errorMessage, false);
      }

      done(null, user); // This works just fine.
    } catch (error) {
      logger.error("Error in local.js.", error?.message);
      return done(error);
    }
  };


  passport.use("login", new LocalStrategy({
    usernameField: "email",
    passwordField: "password",
    passReqToCallback: true,
  }, authenticateUser));


  passport.serializeUser((user, done) => {
    console.log("Serializing user (only _id)...", user._id.toString());
    return done(null, user._id.toString());
  });

  passport.deserializeUser(async (_id, done) => {
    console.log("Deserialize userId: ", _id);
    const user = await userModel.findById(_id);
    const userData = {
      _id: user._id.toString(),
      email: user.email,
      firstname: user.firstname,
      lastname: user.lastname,
    }
    
    done(null, userData);
  });
};

在passportAuth“isAuthenticated()”中,我遇到了邮递员和网络应用程序的问题。当使用邮递员时,它确实工作并执行 next() 函数。但当客户要求时,却没有。
我失去了理智,因为我不明白问题是什么。

我控制台记录的步骤:

点击登录时:

  • 电子邮件和密码有效。

  • 正在序列化用户... (_id)

  • 错误 用户未通过护照进行身份验证!

尝试使用邮递员时...

  • 电子邮件和密码有效。

  • 正在序列化用户... (_id)

  • 反序列化用户...(相同_id)

  • 会话中的护照 ID = { user: "(_id number)" }

  • 护照已验证

  • 发送状态200 OK。

node.js express authentication passport.js passport-local
1个回答
0
投票

我有完全相同的问题。你用的是vite吗?我相信这可能与不包括 cookie 的重定向有关。我本想发表评论,但我的代表太低了。

© www.soinside.com 2019 - 2024. All rights reserved.