Postman请求无响应一直发送,/login路由及LocalStrategy排查求助
问题排查与解决方案
以下是导致请求挂起及返回异常的核心问题和修复方案:
1. SerializeUser 变量名错误
serializeUser 方法的参数是 account,但代码中误用了未定义的 user.id,这会触发 ReferenceError,导致 Passport 无法完成用户序列化,请求因此卡住无法结束。
修复代码:
Passport.serializeUser((account, done) => { done(null, account.id); // 将 user.id 改为 account.id });
2. Login 路由异步操作未正确处理
Login 路由使用了 async 函数,但调用的 accountsQuery.getOneByUsername 是回调风格的方法,await 无法正确处理这类函数,会导致 Promise 永远处于 pending 状态,响应无法发送,请求持续挂起。
有两种修复方式:
- 封装回调函数为 Promise:
// 封装示例 function getOneByUsernamePromise(username) { return new Promise((resolve, reject) => { accountsQuery.getOneByUsername(username, (err, user) => { err ? reject(err) : resolve(user); }); }); } // 路由中使用 app.post('/login', Passport.authenticate('local', {failureRedirect: '/login'}), async (req, res) => { try { const account = await getOneByUsernamePromise(req.body.username); res.status(200).json(account); } catch (err) { res.status(500).json({error: '获取用户信息失败'}); } })
- 直接改用回调风格处理,移除
async/await:
app.post('/login', Passport.authenticate('local', {failureRedirect: '/login'}), (req, res) => { accountsQuery.getOneByUsername(req.body.username, (err, account) => { if (err) return res.status(500).send('服务器内部错误'); res.status(200).json(account); }); })
3. 补充认证失败后的路由
当前设置了 failureRedirect: '/login',但未定义 GET /login 路由,认证失败时会返回 404。添加对应路由:
app.get('/login', (req, res) => { res.status(401).json({message: '用户名或密码错误'}); });
4. 保留 express.json() 中间件
app.use(express.json()) 的位置是正确的,不需要移除。移除它会导致无法解析 POST 请求的 JSON 数据,Passport 拿不到用户名和密码,最终因重定向到不存在的路由返回 404,但这只是掩盖了根本问题。
修复后核心代码片段
// 修复序列化逻辑 Passport.serializeUser((account, done) => { done(null, account.id); }); // 修复登录路由(回调风格) app.post('/login', Passport.authenticate('local', {failureRedirect: '/login'}), (req, res) => { accountsQuery.getOneByUsername(req.body.username, (err, account) => { if (err) return res.status(500).send('服务器内部错误'); res.status(200).json(account); }); }) // 添加登录失败路由 app.get('/login', (req, res) => { res.status(401).json({message: '用户名或密码错误'}); });
完成以上修改后重启服务器,使用 Postman 发送带正确 JSON 格式 username 和 password 的 POST 请求到 /login,即可正常获取响应。
内容的提问来源于stack exchange,提问作者yasin
相关产品推荐
相关产品推荐

