node.js - 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>
解决方案
检查护照本地代码,它似乎Authenticate()
用于验证用户的凭据(用户名,密码),所以基本上你只需要在/login路由中使用它。
要验证用户是否有权访问受保护的路由,您可以req.isAuthenticated()
改用。
例子:
app.get("/secret", (req, res) => {
if (!req.isAuthenticated()) {
return res.sendStatus(401);
}
res.render("secret");
});
推荐阅读
- javascript - 拒绝应用样式',因为它的 MIME 类型 ('text/html') 不是受支持的样式表 MIME 类型,并且启用了严格的 MIME 检查
- javascript - 为什么这个 css 不响应外部图像源?
- r - 使用 ggplot 在分组条形图上定位标签
- python - Selenium WebDriver 上传文件,输入类型为“文本”
- dsl - Xtext 引用来自不同文件的元素不起作用
- flutter - 如果颤动项目,修复迁移到 androidx?
- azure - 当文件 requirements.txt 中未包含所有包时,Python Web 应用程序的部署失败(即使它们已安装在 yaml 任务中))
- maven - JaCoCo 始终显示零覆盖率
- java - 只能导航到第一次点击的额外布局
- javascript - async/await 函数没有像 MDN 网络文档中描述的那样工作