You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,但你的代码未处理这一步。

具体修改步骤

  1. 从登录响应提取会话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 };
    }
    
  2. 在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);
        });
    }
    
  3. 调用时传递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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 13:45:32