React客户端使用Passport认证异常:上传请求无法通过isLoggedIn中间件
MERN栈会话认证问题:前端上传请求无法通过isLoggedIn中间件
我正在开发基于MERN栈的应用,使用Passport、passport-local和passport-local-mongoose实现会话式认证。前端包含登录页、注册页和上传路由,后端采用Node.js与MongoDB。登录时服务器返回成功,但上传请求无法通过isLoggedIn中间件;然而使用Hoppscotch工具时,登录及上传请求均能正常执行。
相关代码
登录页组件
import axios from "axios"; import React, { useState } from "react"; import "./login.css"; const Login = (props) => { const [username, setUsername] = useState(); const [password, setPassword] = useState(); const onSubmit = (e) => { e.preventDefault(); const obj = { username: username, password: password }; axios .post("http://localhost:4000/api/login", obj) .then((res) => { console.log("login response: ", res); if(res.status === 200) { alert("Logged in!!!"); // window.location.href = "/"; } }) .catch((e) => { alert("error"); console.log(e); }); }; return ( <div className="cont"> <form className="input" onSubmit={onSubmit}> <label className="label" htmlFor="username">Username:</label> <input className="input" type="text" id="username" onChange={(e) => setUsername(e.target.value)} /> <label className="label" htmlFor="password">Password:</label> <input className="input" type="password" id="password" onChange={(e) => setPassword(e.target.value)} /> <button className="button" type="submit" value="submit"> Submit </button> </form> </div> ); }; export default Login;
上传页组件
import React, { useState } from "react"; import axios from "axios"; const Home = () => { const [file, setFile] = useState(); const onSubmit = (e) => { e.preventDefault(); const data = new FormData(); data.append("file", file); axios .post("http://localhost:4000/api/upload/resume", data, { withCredentials: true, headers: { "Content-Type": "multipart/form-data" }, }) .then((file) => { console.log("worked ", file); }) .catch((e) => { console.log(e); }); }; return ( <form onSubmit={onSubmit}> <p>Submit your resume pdf here ( Resume pdf should be 12 Mb or less )</p> <input type="file" id="pdf-file" onChange={(e) => setFile(e.target.files[0])} /> <button type="submit">Upload</button> </form> ); }; export default Home;
登录路由(后端)
router.post("/login", (req, res, next) => { passport.authenticate("local", (err, user, info) => { if (err) throw err; if (!user) res.send("No User Exists"); else { req.logIn(user, (err) => { if (err) throw err; res.send("Successfully Authenticated"); console.log(req.user); }); } })(req, res, next); });
isLoggedIn中间件(后端)
const isLoggedIn = (req, res, next) => { console.log(req); if (req.isAuthenticated()) { console.log("authenticated"); return next(); } console.log("not authenticated"); throw new Error("User not authenticated"); }; module.exports = isLoggedIn;
问题原因及解决办法
核心问题是登录请求未携带凭证,导致会话Cookie未被前端保存,后续上传请求的身份验证自然失效。Hoppscotch默认自动保存并发送Cookie,因此测试正常。
具体修复步骤:
给登录请求添加凭证配置
修改登录页的axios请求,加入withCredentials: true,确保会话Cookie被前端保存:axios .post("http://localhost:4000/api/login", obj, { withCredentials: true }) .then((res) => { console.log("login response: ", res); if(res.status === 200) { alert("Logged in!!!"); } }) .catch((e) => { alert("error"); console.log(e); });后端配置允许跨域凭证
如果使用cors包,需明确开启允许携带凭证:const cors = require('cors'); app.use(cors({ origin: "http://localhost:3000", // 替换为你的前端地址 credentials: true }));移除上传请求的手动Content-Type设置
axios会自动为FormData生成包含boundary的正确multipart/form-data头,手动设置会导致验证错误:axios .post("http://localhost:4000/api/upload/resume", data, { withCredentials: true // 删除此行:headers: { "Content-Type": "multipart/form-data" }, })检查会话中间件配置
确保express-session的Cookie参数设置合理,适配开发/生产环境:const session = require('express-session'); app.use(session({ secret: 'your-secure-secret-key', resave: false, saveUninitialized: false, cookie: { httpOnly: true, sameSite: 'lax', // HTTPS跨域环境可设为'none' secure: process.env.NODE_ENV === 'production' } }));
内容的提问来源于stack exchange,提问作者Dark Ghoul
相关产品推荐
相关产品推荐

