简体   繁体   English

Set-Cookie header 中的 Cookie 未设置

[英]Cookie in Set-Cookie header not being set

I'm sending a request to a node.js server from a reactjs client using axios as shown below.我正在使用 axios 从 reactjs 客户端向 node.js 服务器发送请求,如下所示。

import axios from 'axios';

const apiClient = axios.create({
  withCredentials: true,
  baseURL: 'http://localhost:8080'
});

async function(payload) {
  try {
    debugger;
    let result = await apiClient.post('/auth/signup/', payload);
    debugger;
    return result;
  } catch (error) {
    debugger;
    throw error;
  }
}

The node.js endpoint sets a cookie in the response as shown below. node.js 端点在响应中设置一个 cookie,如下所示。

const express = require('express');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser')
const cors = require('cors');
const jwt = require('jsonwebtoken');

router.use(bodyParser.json());
router.use(bodyParser.urlencoded({ extended: true }));
router.use(cors({ origin: 'http://localhost:3000', credentials: true, exposedHeaders: ['Set-Cookie', 'Date', 'ETag']} ));
router.use(cookieParser());


router.post('/signup', async (req, res, next) => {
  debugger;
  let database = req.app.locals.database;
  try {
    let user = await database.findByUsername(req.body.username);
    let token = await jwt.sign({username: user.username}, config.secret, {expiresIn: "15m"});
    res.cookie('jwt',  token, {
      maxAge: 900,
    });
  } catch (error) {
    debugger;
    return res.status(503).send({ auth: false, message: 'Database error.' });
  }
});

The Set-Cookie header of the response contains the cookie as expected.响应的 Set-Cookie header 包含预期的 cookie。

设置 Cookie 标头

However, Chrome does not appear to be setting the cookie, as I cannot see the cookie in the Application window of the Developer Console.但是,Chrome 似乎没有设置 cookie,因为我在开发人员控制台的应用程序 window 中看不到 cookie。

饼干

I've looked at the answers to the following questions, which mention setting { withCredentials: true } in the axios configuration and not using a wildcard origin for cors in node.js, but I am already doing both.我查看了以下问题的答案,其中提到在 axios 配置中设置{ withCredentials: true }并且不使用 cors 的通配符来源 Z28A3689BE95C88DD4E7A37DB516AB0

Set-Cookie header not setting cookie in Chrome Set-Cookie header 未在 Chrome 中设置 cookie

Set cookies for cross origin requests 为跨源请求设置 cookies

Any ideas as to why the cookie is not being set and how to fix this issue?关于为什么未设置 cookie 以及如何解决此问题的任何想法?

Here's a repost of my answer on a similar question https://stackoverflow.com/a/62821342/8479303这是我对类似问题https://stackoverflow.com/a/62821342/8479303的回答的转贴


In my case, the network panel showed that the response had the 'Set-Cookie' header, but in axios the header wouldn't show up, and the cookie was being set.在我的情况下,网络面板显示响应具有“Set-Cookie”header,但在 axios 中,header 不会显示,并且 cookie 已设置。

For me, the resolution was setting the Access-Control-Expose-Headers header.对我来说,解决方案是设置Access-Control-Expose-Headers header。

For explanation, from this comment on an issue in the axios repository I was directed to this person's notes which led me to set the Access-Control-Expose-Headers header -- and now the cookie is properly setting in the client.为了解释,从 axios 存储库中的一个问题的评论中,我被引导到这个人的笔记,这导致我设置Access-Control-Expose-Headers header - 现在cookie在客户端中正确设置。

So, in Express.js, I had to add the exposedHeaders option to my cors middleware:因此,在 Express.js 中,我必须将暴露的Headers 选项添加到我的exposedHeaders中间件中:

const corsOptions = {
  //To allow requests from client
  origin: [
    "http://localhost:3001",
    "http://127.0.0.1",
    "http://104.142.122.231",
  ],
  credentials: true,
  exposedHeaders: ["set-cookie"],
};

...

app.use("/", cors(corsOptions), router);

It was also important that on the axios side I use the withCredentials config in following axios requests that I wanted to include the cookies.同样重要的是,在 axios 方面,我在以下 axios 请求中使用withCredentials配置,我想包括 cookies。

ex/前任/

const { data } = await api.get("/workouts", { withCredentials: true });

Though you are hosting client and server in the same domain as http://localhost , your ports are different, so the same-origin policy is failed here.虽然您将客户端和服务器托管在与http://localhost相同的域中,但您的端口不同,因此同源策略在这里失败。 You can check https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy .您可以查看https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

As so, you making a CORS request, check your network tab in your developer tools in your current browser, you might see a preflight request OPTIONS , before your client sends POST request to your server.因此,您发出 CORS 请求,在您当前浏览器的开发人员工具中检查您的网络选项卡,在您的客户端向您的服务器发送POST请求之前,您可能会看到一个预检请求OPTIONS

The server must specify headers to accept the origin of your next request - POST request from http://localhost:8000 with method POST , you can refer to https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request服务器必须指定标头以接受下一个请求的来源 - 来自http://localhost:8000的 POST 请求,使用方法POST ,您可以参考https://developer.mozilla.org/en-US/docs/Glossary/ Preflight_request

HTTP/1.1 204 No Content
Connection: keep-alive
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: POST // Your next request will use POST method
Access-Control-Max-Age: 86400
Access-Control-Allow-Credentials: true // cookies accepted

Added:添加:

In Set-Cookie , Max-Age must be non-zero digit .Set-Cookie中, Max-Age必须是非零数字 It be rounded up into integer according to RFC doc .根据RFC doc将其四舍五入为 integer 。 For express.js, cookies `maxAge property is on the scale of miliseconds对于 express.js,cookies `maxAge 属性以毫秒为单位

The solution will be set the maxAge property as second * 1000解决方案将maxAge属性设置为second * 1000

    res.cookie('jwt',  token, {
      maxAge: 10000,
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM