Cookie 不会通过“Set-Cookie”标头在 Chrome 中设置

stu*_*lyf 2 google-chrome web-development-server node.js express next.js

我在前端 (Next.JS) 中通过 Express.JS 设置 cookie 时遇到一些问题。

这些是我从 API ( /login) 返回的标头:

Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 354
Content-Type: application/json; charset=utf-8
Date: Sun, 21 Mar 2021 19:34:19 GMT
ETag: W/"162-9yg5khk3mdMK+w5SIteR+26LIrw"
Keep-Alive: timeout=5
Set-Cookie: refresh_token=<INSERT REFRESH_TOKEN HERE>; Max-Age=2592000; Expires=Tue, 20 Apr 2021 19:34:19 GMT; HttpOnly
X-Powered-By: Express
Run Code Online (Sandbox Code Playgroud)

这是 Express 后端的代码:

Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 354
Content-Type: application/json; charset=utf-8
Date: Sun, 21 Mar 2021 19:34:19 GMT
ETag: W/"162-9yg5khk3mdMK+w5SIteR+26LIrw"
Keep-Alive: timeout=5
Set-Cookie: refresh_token=<INSERT REFRESH_TOKEN HERE>; Max-Age=2592000; Expires=Tue, 20 Apr 2021 19:34:19 GMT; HttpOnly
X-Powered-By: Express
Run Code Online (Sandbox Code Playgroud)

(我还尝试将域设置为localhostpath到一切可以想象的)

这是cookieMiddleware

app.post('/login', cookieMiddleware, async (req, res) => {
    try {
        console.log('login now happening');

        if (!req.body.code) throw new Error('no code was provided.');
        const code = req.body.code;

        const data = await fetchToken(
            code,
            CREDENTIALS.REDIRECT_URI,
            CREDENTIALS.CLIENT_SECRET,
            CREDENTIALS.CLIENT_ID,
        );

        res.cookie('refresh_token', data.refreshToken, {
            httpOnly: true,
            maxAge: 30 * 24 * 60 * 60 * 1000,
        });

        res.status(200).json(data);
        res.end();
        return;
    } catch (err) {
        res.status(500);
        res.end();
        return;
    }
});
Run Code Online (Sandbox Code Playgroud)

在 Chrome 中,即使我将其设置为非 cookie,cookie 也不会显示httpOnly

我总是从中间件的控制台中得到这个:

Cookies:  {}
Signed Cookies:  {}
Run Code Online (Sandbox Code Playgroud)

编辑: 我现在已经用 Postman 测试了它,它可以工作,但与 chrome/通过前端的结果仍然相同。

编辑2:

我已将答案写在下面,这应该可以解决所有问题。

stu*_*lyf 6

我已经找到答案了

问题在于cors-api fetch

要设置 cookie,您需要在前端执行以下操作:

fetch('<DOMAIN>/<PATH>',
    {
        ...
        credentials: 'include',
        mode: 'cors'
    }
)
Run Code Online (Sandbox Code Playgroud)

这在后端:

app.use(
    cors({
        credentials: true,
        origin: '<DOMAIN>'
    })
)
Run Code Online (Sandbox Code Playgroud)

但您必须向后端提供完整的原始 URL,例如:
您的前端运行在 * ** 上localhost:3000,您的后端运行在 * ** 上localhost:8080。这将是您的前端代码

fetch('http://localhost:8080/login', {
        ...
        credentials: 'include',
        mode: 'cors'
        ...
    }
)
Run Code Online (Sandbox Code Playgroud)

那么这将是后端代码

app.use(
    cors:({
        credentials: true,
        origin: 'http://localhost:3000'
    })
)
Run Code Online (Sandbox Code Playgroud)

使用相同的方法,您可以将 Cookie 发送回您的 API。