【问题标题】:Cannot set cookie from backend express api to frontend next(react) app - both on localhost无法将 cookie 从后端 express api 设置到前端 next(react) 应用程序 - 都在本地主机上
【发布时间】:2021-06-11 14:52:49
【问题描述】:

目前我正在尝试在登录获取后将 JWT 令牌保存在客户端 cookie 中。在开发工具的 Network 选项卡中查看 set-cookie 响应时,我得到 This set cookie was blocked because its domain attribute was invalid with regards to the current host url.

这是我用来设置 cookie 的代码:

const token = user.generateVerificationToken();
const cookieOptions = {
    domain: 'http://dev.com:3000',
    // expires: new Date(Date.now() + 60000),
    maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
    httpOnly: true,
    secure: req.secure || req.headers['x-forwarded-proto'] === 'https',
};
  
res.cookie('jwt', token, cookieOptions);

这些是 cors 设置:

app.use( cors({credentials: true, origin: 'http://dev.com:3000'}) );

这是客户端上获取请求的样子:

let res = await fetch( 'http://api.dev.com:4000/login', {
        body: JSON.stringify(data), // login data
        headers: {
            'Content-Type': 'application/json'
        },
        method: 'POST',
        credentials: 'include'
    })

/etc/hosts:

127.0.0.1 dev.com
127.0.0.1 api.dev.com

有人可以帮忙吗?我找不到需要做些什么来解决这个问题。

【问题讨论】:

    标签: javascript node.js express cookies fetch


    【解决方案1】:

    这与 CORS 无关。相反,这是 cookie 的问题(跨域问题)。

    您正在尝试为dev.com:3000 设置一个cookie,但API 位于api.dev.com:4000。它是跨域跨域的,因此它是无效的cookie。

    如果我没记错的话,您不可能将 cookie 设置到不同的域。如果这样的事情是可能的,那将是一个严重的安全问题。

    因此,您的问题有两种可能的解决方案:

    • 如果您真的想为dev.com:3000 设置cookie,可行的解决方法是从您的API 中将cookie 值作为res 对象提供,然后在前端 ,你把res 变成一个cookie。您可以为此使用各种 JavaScript 的 API 或插件,例如 document.cookiereact-cookieuniversal-cookiejs-cookie 等等。
    • 如果您征求我的意见,只需将 api.dev.com:4000 转换为 api.dev.com:3000,或在同一个端口上运行它们。可以从同一域来源发送 cookie。
    • 我注意到您正在使用 Next.js。您可以使用无服务器 API 从后端接收 cookie(您仍然必须通过 res 发送 cookie),然后使用无服务器 API 设置 cookie。由于无服务器 API 和前端位于同一 4000 端口,因此 cookie 应该是有效的。这样,您可以保留 cookie 的 httpOnly 属性。

    如需进一步参考,请参阅我在this question 上的回答。

    【讨论】:

    • 感谢这真的有助于解决问题。在您说“将 api.dev.com:4000 更改为 api.dev.com:3000”的地方,我该如何在本地环境中执行此操作。因为在生产中它们将位于同一个端口(不同的服务器,同一个域),但是对于本地开发,我该如何去做。我是否需要在 /etc/hosts 中进行编辑,是否需要代理请求或其他内容?
    • 我以为你在开发中使用api.dev.com?如果您使用不同的子域,应该可以更改端口。但是,如果您使用的是localhost,则只需将origin 设置为*。不要忘记在生产中更改它。
    • 我的回答对您有帮助吗?如果是,请将其标记为已接受。谢谢。
    猜你喜欢
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-02-23
    • 2020-12-29
    相关资源
    最近更新 更多