Passport.js登录后无法获取会话ID/Cookie,后续请求未认证求助
会话维持问题:登录后调用sendFunds接口提示未认证
我用accountGenerator.js实现用户登录并维持会话,登录流程看起来正常——passport.authenticate、passportConfig和serializeUser都被调用,响应也是200 OK,但调用sendFunds接口时返回User is not authenticated。用Postman测试一切正常,推测是Postman自动携带了登录时获取的Cookie。现在需要在accountGenerator.js里获取这个Cookie并在sendFunds请求中携带,但不知道怎么操作,也不确定是否需要手动把Cookie添加到express-session里?
相关代码
accountGenerator.js
async function loginUser(userLogin) { return post('http://localhost:3002/api/user/login', userLogin) } function sendFunds(transferDetails) { post('http://localhost:3002/api/user/sendFunds', transferDetails) .then((res) => { console.log(`Status: ${res.status}`); }).catch((err) => { console.error(err); }); } const loginResponse = await loginUser(userLogin);
后端登录&sendFunds接口
export function loginUser(req, res) { if (req.isAuthenticated()) { res.status(200).send({ message: 'User is authenticated' }); return; } passport.authenticate("local", { successRedirect: "/", failureRedirect: "/error" // failureRedirect: "/login" })(req, res, next); } export function sendFunds(req, res) { if (!req.isAuthenticated()) { res.status(401).send({ message: 'User is not authenticated' }); return; } req.body.secretKey = AUTHENTICATOR_SECRET_KEY; post(SEND_FUNDS_API_URL, req.body) .then((response) => { res.status(200).send(response.data); }).catch((err) => { console.error(err); res.status(500).send(err); }); }
Passport配置
export function passportConfig() { passport.use('local', new LocalStrategy( async (username, password, done) => { const response = await User.findOne({ name: username }); if (!response) { return done(null, false, { message: 'Incorrect username.' }); } const isValidPassword = await compare(password, response.password); if (!isValidPassword) { return done(null, false, { message: 'Incorrect password.' }); } return done(null, response); } )) } passport.serializeUser((user, done) => { done(null, user.id) }) passport.deserializeUser((id, done) => { User.findById(id, (err, user) => { done(err, user) }) })
express-session配置
app.use(expressSession({ store: new MongoStore({ mongoUrl: 'mongodb://127.0.0.1:27017/accountBankApp', // mongooseConnection: mongoose, ttl: 1 * 24 * 60 * 60, // = 365 days. }), secret: 'secret', resave: true, saveUninitialized: true, }));
解决方案
核心原因
你的后端通过express-session+Passport维持会话,登录时服务端会返回包含会话ID的Cookie(默认名为connect.sid),后续请求必须携带这个Cookie才能被识别为已认证用户。Postman会自动保存并携带Cookie,但你的代码未处理这一步。
具体修改步骤
从登录响应提取会话Cookie
修改loginUser函数,从响应头中提取会话Cookie:async function loginUser(userLogin) { const response = await post('http://localhost:3002/api/user/login', userLogin); // 提取会话Cookie(取set-cookie数组第一个,截断到分号前的有效内容) const sessionCookie = response.headers['set-cookie']?.[0]?.split(';')[0]; return { response, sessionCookie }; }在sendFunds请求中携带Cookie
修改sendFunds函数,添加Cookie请求头:function sendFunds(transferDetails, sessionCookie) { post('http://localhost:3002/api/user/sendFunds', transferDetails, { headers: { Cookie: sessionCookie } }) .then((res) => { console.log(`Status: ${res.status}`); }).catch((err) => { console.error(err); }); }调用时传递Cookie
调整调用逻辑,确保登录成功后传递会话Cookie:const { response, sessionCookie } = await loginUser(userLogin); if (response.status === 200 && sessionCookie) { sendFunds(transferDetails, sessionCookie); }
补充说明
- 不需要手动将Cookie添加到
express-session,服务端的express-session会自动根据请求携带的Cookie识别会话,你只需要确保客户端请求带上正确的Cookie即可。 - 如果使用的
post工具不是axios(比如node-fetch),提取Cookie的方式略有不同:通过response.headers.getSetCookie()获取Cookie数组,携带方式同样是在请求头添加Cookie字段。
内容的提问来源于stack exchange,提问作者whokilledann
相关产品推荐
相关产品推荐

