首页 > 解决方案 > Browsers block CORS cookie

问题描述

I´m using Firebase Functions hosted with Firebase Hosting on a custom domain - api.example.com.

When the user does log in on my website a request to the server is sent

await fetch(`https://api.example.com/test`, {
        method: 'POST',
    credentials: 'include',
    })
        .then(async function (response) {
            if (response.status == 200) {
                let text = await response.text();
                console.log(text);
            }
            else {
                console.log("Failed");
                return null;
            }
        });

in Cloud Functions the test endpoint is triggered which looks the following:

exports.test = functions
    .https.onRequest((request, response) => {
        const expiresIn = 60 * 60 * 24 * 5 * 1000;
        const origin = request.headers.origin;

        const options = { maxAge: expiresIn, httpOnly: true, secure: true, sameSite: 'None'};
        response.cookie('__session', "123456", options);
        response.set('Access-Control-Allow-Origin', origin);
        response.set('Access-Control-Allow-Credentials', true);
        response.set('Access-Control-Allow-Headers', 'credentials');
        response.end(JSON.stringify({ status: 'success' }));
})

The problem is: The browser dev tools of mozilla, chrome, safari show the response of the server where the header contains set-cookie: __session=123456; Max-Age=432000; Path=/; Expires=Mon, 30 Aug 2021 11:25:25 GMT; HttpOnly; Secure; SameSite=None BUT the cookie is not stored in Mozilla Firefox and Safari. In Chrome it is stored but gets deleted after page refresh although it should persist.

What am I doing wrong here? Any suggestions?

标签: firebasegoogle-chromecookiesgoogle-cloud-functionscross-domain

解决方案


I found the solution. I haven't specified a domain for the cookie options.

It should look like the following:

exports.test = functions
    .https.onRequest((request, response) => {
        const expiresIn = 60 * 60 * 24 * 5 * 1000;
        const origin = request.headers.origin;

        const options = { maxAge: expiresIn, httpOnly: true, secure: true, sameSite: 'None', domain: 'example.com'};
        response.cookie('__session', "123456", options);
        response.set('Access-Control-Allow-Origin', origin);
        response.set('Access-Control-Allow-Credentials', true);
        response.set('Access-Control-Allow-Headers', 'credentials');
        response.end(JSON.stringify({ status: 'success' }));
})

推荐阅读