使用Express和PassportJS时出现Cannot POST /login错误的排查
问题:POST /login 返回 Cannot POST /login,但日志显示请求已被处理
发送包含用户登录数据的POST请求到/login时,收到Cannot POST /login响应,但日志显示请求已被处理。使用Postman和HTML表单测试均无效,Passport.js出错时能正常记录日志。
相关代码
server.js(精简版)
const express = require("express"); const cors = require("cors"); const flash = require("express-flash"); const passport = require("passport"); const session = require("express-session"); //app configuration const app = express(); require("dotenv").config(); const initializePassport = require("./config/passport-config"); initializePassport( passport, require('./models/User') ) app.use( session({ secret: "Janniks whatsapp Klon", resave: false, saveUninitialized: false, }) ); app.use(passport.initialize()); app.use(passport.session()); //For accepting post from data const UserRouter = require("./api/User"); app.use(flash()); app.use(express.json()); app.use(bodyarser.urlencoded({ extended: true })); app.use( cors() //{ origin: "http://localhost:3000", origin: "http://localhost:3000" } ); app.use("/user", UserRouter); app.post('/login', passport.authenticate('local', { sucessRedirect: 'http://localhost:3000/login', failureRedirect: 'http://localhost:3000/login', failureFlash: true }), )
passport-config.js
const passport = require('passport') const LocalStrategy = require('passport-local').Strategy const bcrypt = require('bcrypt') //Password handle function initialize(passport, User){ const authenticateUser = async(emailORnumber, password, done)=>{ //Find user with email or phone number let user; if(emailORnumber.includes('@')){ user = await User.findOne({ email: emailORnumber}) }else{ user = await User.findOne({ number: emailORnumber }) } if(!user){ //User not found, error console.log('User not found') return done(null, false, { message: 'Falsches passwort oder falsche Handynummer' }) } //Check if password is correct try{ console.log('Checking password') const isMatch= await bcrypt.compare(password, user.password); if(!isMatch){ return done(null, false, { message: 'Falsches passwort'}) }else{ //If credentials are correct, return the user object console.log('correct') //gets logged return done(null, user) } } catch(err){ console.log(err) return done(err) } } passport.use(new LocalStrategy({ usernameField: 'emailORnumber'}, authenticateUser)), //Serialize user to store passport.serializeUser((user, done)=>{ console.log('Serializing user') //gets logged done(null, user.id) }) //Deserialize user from store passport.deserializeUser((id, done)=>{ console.log('Serializing user') //dont gets logged but there is no interaction User.findById(id, (err, user)=>{ return done(err, user); }); }); } module.exports = initialize;
解决方案
1. 修复body-parser的引入与拼写错误
代码中使用了未引入的bodyarser(拼写错误),需先安装并正确引入:
npm install body-parser
修改server.js:
// 新增引入 const bodyParser = require("body-parser"); // 替换原错误行 app.use(bodyParser.urlencoded({ extended: true }));
2. 修正successRedirect拼写错误
登录路由中sucessRedirect少写了一个c,导致重定向失效,修正为:
app.post('/login', passport.authenticate('local', { successRedirect: 'http://localhost:3000/', // 建议跳转到主页而非登录页 failureRedirect: 'http://localhost:3000/login', failureFlash: true }));
3. 修复passport-config.js的语法错误
passport.use行末尾多余的逗号会导致语法问题,移除:
passport.use(new LocalStrategy({ usernameField: 'emailORnumber'}, authenticateUser));
4. 修正序列化日志描述(可选)
deserializeUser中的日志描述有误,修正为:
passport.deserializeUser((id, done)=>{ console.log('Deserializing user') // 原日志写为Serializing,与功能不符 User.findById(id, (err, user)=>{ return done(err, user); }); });
额外检查点
- 确保HTML表单的
action="/login"、method="POST",且字段名与usernameField一致(emailORnumber和password) - Session的secret建议使用环境变量,避免硬编码泄露风险
- 验证CORS配置是否符合你的前端域名需求
内容的提问来源于stack exchange,提问作者Jannik Stach
相关产品推荐
相关产品推荐

