首页 > 解决方案 > Express 路由之间的 Passport.js 身份验证不一致

问题描述

我正在尝试将护照身份验证与 passport-local-mongoose 提供的本地策略一起使用来验证用户身份。如果用户通过身份验证,则允许他查看 /secret 路由,否则他会收到错误的请求消息(由护照提供)。

奇怪的部分是身份验证适用于登录 POST 路由,该路由在正确的凭据后成功重定向到 /secret 页面。但是在重定向时,用户会收到一个错误的请求,这意味着 /secret 路由的身份验证失败。这是非常令人困惑的,因为如果用户在登录时成功通过身份验证,他只能被重定向到 /secret,但在重定向到 /secret 时,身份验证失败并发送错误的请求错误。

用户架构:

const mongoose = require("mongoose"),
    passportLocalMongoose = require("passport-local-mongoose");

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

userSchema.plugin(passportLocalMongoose);

module.exports = new mongoose.model("User", userSchema);

服务器配置:

const express = require("express"),
    mongoose = require("mongoose"),
    passport = require("passport"),
    bodyParser = require("body-parser"),
    LocalStrategy = require("passport-local"),
    expressSession = require("express-session");

const User = require("./models/user");

const app = express();

app.set("view engine", "ejs");
app.use(
    expressSession({
        secret: "Lorem Ipsum",
        resave: false,
        saveUninitialized: false
    })
);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());

mongoose.connect("mongodb://localhost:27017/auth-test", {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

登录和秘密路线:

app.post(
    "/login",
    passport.authenticate("local", {
        successRedirect: "/secret",
        failureRedirect: "/register"
    })
);

app.get("/secret", passport.authenticate("local"), (req, res) => {
    res.render("secret");
});

登录表单以备不时之需,用于 /login GET 路由:

<form action="/login" method="POST">
    <input type="text" placeholder="Username" name="username" autocomplete="off" />
    <input type="password" placeholder="Password" name="password" autocomplete="off" />
    <button type="submit">Submit</button>
</form>

标签: node.jsexpressmongoosepassport.jsexpress-session

解决方案


检查护照本地代码,它似乎Authenticate()用于验证用户的凭据(用户名,密码),所以基本上你只需要在/login路由中使用它。

要验证用户是否有权访问受保护的路由,您可以req.isAuthenticated()改用。

例子:

app.get("/secret", (req, res) => {
  if (!req.isAuthenticated()) {
    return res.sendStatus(401);
  }
  res.render("secret");
});

推荐阅读