因此,我有一个简单的 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。
我有完全相同的问题。你用的是vite吗?我相信这可能与不包括 cookie 的重定向有关。我本想发表评论,但我的代表太低了。