【问题标题】:Passport.js authentication inconsistent between Express routesExpress 路由之间的 Passport.js 身份验证不一致
【发布时间】:2020-04-29 07:23:10
【问题描述】:

我正在尝试将护照身份验证与 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>

【问题讨论】:

  • /secret 路由之前添加一个日志只是为了确保会话被存储,app.use((req, res, next) =&gt; { console.log(req.session); next(); });
  • 会话似乎已存储。这是日志:Session {cookie: Cookie, req: IncomingMessage, id: "DCZ6v0MrgLhjXcauyfj22mS1A3b8brjI", reload: , save: }

标签: node.js express mongoose passport.js express-session


【解决方案1】:

检查passport-local code,似乎Authenticate() 是用来验证用户的凭据(用户名、密码),所以基本上你只需要在/login中使用它路线。

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

示例:

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

【讨论】:

  • 非常感谢。这非常令人沮丧。如果their website 提到isAuthenticated() 一次,这整件事本可以避免。
猜你喜欢
  • 2017-03-31
  • 1970-01-01
  • 2015-11-01
  • 2013-06-29
  • 2014-11-06
  • 1970-01-01
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
相关资源
最近更新 更多