Set-Cookie header 中的 Cookie 未设置
Cookie in Set-Cookie header not being set
我正在使用 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;
}
}
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.' });
}
});
响应的 Set-Cookie header 包含预期的 cookie。
但是,Chrome 似乎没有设置 cookie,因为我在开发者控制台的应用程序 window 中看不到 cookie。
我查看了以下问题的答案,其中提到了在 axios 配置中设置 { withCredentials: true }
并且在 node.js 中没有为 cors 使用通配符来源,但我已经在做这两个问题.
Set-Cookie header not setting cookie in Chrome
对于未设置 cookie 的原因以及如何解决此问题有任何想法吗?
虽然您在与 http://localhost
相同的域中托管客户端和服务器,但您的端口不同,因此 same-origin 策略在这里失败。您可以查看 https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.
因此,如果您发出 CORS 请求,请在当前浏览器的开发人员工具中检查您的网络选项卡,在您的客户端发送 POST
请求之前,您可能会看到预检请求 OPTIONS
你的服务器。
服务器必须指定 headers 以接受您下一个请求的来源 - POST 来自 http://localhost:8000
的请求,方法 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
已添加:
在Set-Cookie
中,Max-Age
必须是non-zero digit. It be rounded up into integer according to RFC doc. For express.js, cookies `maxAge property is on the scale of miliseconds
解决方案将 maxAge
属性 设置为 second * 1000
res.cookie('jwt', token, {
maxAge: 10000,
});
这是我对类似问题的回答的转贴 https://whosebug.com/a/62821342/8479303
在我的例子中,网络面板显示响应有 'Set-Cookie' header,但在 axios 中 header 不会出现,并且正在设置 cookie .
对我来说,解决方案是设置 Access-Control-Expose-Headers
header。
为了解释,来自 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 -- 现在 cookie 已在客户端中正确设置。
因此,在 Express.js 中,我必须将 exposedHeaders
选项添加到我的 cors 中间件中:
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);
同样重要的是,在 axios 方面,我在以下我想包含 cookie 的 axios 请求中使用 withCredentials
配置。
ex/
const { data } = await api.get("/workouts", { withCredentials: true });
我正在使用 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;
}
}
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.' });
}
});
响应的 Set-Cookie header 包含预期的 cookie。
但是,Chrome 似乎没有设置 cookie,因为我在开发者控制台的应用程序 window 中看不到 cookie。
我查看了以下问题的答案,其中提到了在 axios 配置中设置 { withCredentials: true }
并且在 node.js 中没有为 cors 使用通配符来源,但我已经在做这两个问题.
Set-Cookie header not setting cookie in Chrome
对于未设置 cookie 的原因以及如何解决此问题有任何想法吗?
虽然您在与 http://localhost
相同的域中托管客户端和服务器,但您的端口不同,因此 same-origin 策略在这里失败。您可以查看 https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.
因此,如果您发出 CORS 请求,请在当前浏览器的开发人员工具中检查您的网络选项卡,在您的客户端发送 POST
请求之前,您可能会看到预检请求 OPTIONS
你的服务器。
服务器必须指定 headers 以接受您下一个请求的来源 - POST 来自 http://localhost:8000
的请求,方法 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
已添加:
在Set-Cookie
中,Max-Age
必须是non-zero digit. It be rounded up into integer according to RFC doc. For express.js, cookies `maxAge property is on the scale of miliseconds
解决方案将 maxAge
属性 设置为 second * 1000
res.cookie('jwt', token, {
maxAge: 10000,
});
这是我对类似问题的回答的转贴 https://whosebug.com/a/62821342/8479303
在我的例子中,网络面板显示响应有 'Set-Cookie' header,但在 axios 中 header 不会出现,并且正在设置 cookie .
对我来说,解决方案是设置 Access-Control-Expose-Headers
header。
为了解释,来自 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 -- 现在 cookie 已在客户端中正确设置。
因此,在 Express.js 中,我必须将 exposedHeaders
选项添加到我的 cors 中间件中:
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);
同样重要的是,在 axios 方面,我在以下我想包含 cookie 的 axios 请求中使用 withCredentials
配置。
ex/
const { data } = await api.get("/workouts", { withCredentials: true });