即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie
Nodejs won't set cookie for React CRA application even with proxy
我有一个 nodejs/express + React CRA 应用程序,我正在尝试从 nodejs 设置一个 cookie。服务器在端口 4001 上,所以在我的 React 应用程序的 project.json 中我设置了 "proxy": "http://localhost:4001"
,但 cookie 仍然不会在浏览器中设置。
我也在生产模式下对其进行了测试,React 应用程序直接从 nodejs 提供,一切正常。
这是我设置 cookie 的方式。我在这里尝试了几种不同的选项组合,它们都有相同的结果。
res.cookie('jwt', token, {
httpOnly: false,
sameSite: false,
signed: false,
secure: false,
encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');
编辑:在客户端,我使用 Axios 处理我的 ajax 请求。
编辑:
这里是登录端点函数(POST /api/users/login):
login: function(req, res) {
User.findOne({
$or: [{email: req.body.username}, {username: req.body.username}]
}).exec().then(user => {
if(user) {
if(user.checkPassword(req.body.password)) {
jwt.sign({ userID: user._id }, 'secret', (err, token) => {
res.cookie('jwt', token, {
httpOnly: false,
sameSite: false,
signed: false,
secure: false,
encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');
res.status(200).send({ status: 'ok', message: 'Success'});
});
}
else {
return res.status(401).send({ status: 'error', message: 'Invalid username/password combination. Please try again.' });
}
}
else {
return res.status(401).send({ status: 'error', message: 'Invalid username/password combination. Please try again.' });
}
}, err => {
return res.status(500).send({ status: 'error', message: 'unexpected error' });
});
}
这是客户端登录代码:
login(username, password) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: 'http://localhost:4001/api/users/login',
data: {
username,
password
}
}).then((res) => {
resolve(res.data);
}, (err) => {
reject(err);
});
});
}
服务器在端口 4001,React CRA 服务器在 3000
为了允许浏览器设置 cookie 并遵守同源策略,您的客户端代码应该查询 http://localhost:3000/api/users/login
(与客户端相同的主机)而不是(代理)服务器 url(端口 4001 ).
您还可以将基数 url 指定为 ${window.location.origin}/api
或仅 /api
.
根据 riwu 提到的 cookie 域应该匹配,在我的情况下设置 "cookieDomainRewrite": "localhost",
有效
下面是 React 中 setupProxy.js
的完整配置:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8000',
changeOrigin: true,
cookieDomainRewrite: "localhost",
})
);
};
我有一个 nodejs/express + React CRA 应用程序,我正在尝试从 nodejs 设置一个 cookie。服务器在端口 4001 上,所以在我的 React 应用程序的 project.json 中我设置了 "proxy": "http://localhost:4001"
,但 cookie 仍然不会在浏览器中设置。
我也在生产模式下对其进行了测试,React 应用程序直接从 nodejs 提供,一切正常。
这是我设置 cookie 的方式。我在这里尝试了几种不同的选项组合,它们都有相同的结果。
res.cookie('jwt', token, {
httpOnly: false,
sameSite: false,
signed: false,
secure: false,
encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');
编辑:在客户端,我使用 Axios 处理我的 ajax 请求。
编辑:
这里是登录端点函数(POST /api/users/login):
login: function(req, res) {
User.findOne({
$or: [{email: req.body.username}, {username: req.body.username}]
}).exec().then(user => {
if(user) {
if(user.checkPassword(req.body.password)) {
jwt.sign({ userID: user._id }, 'secret', (err, token) => {
res.cookie('jwt', token, {
httpOnly: false,
sameSite: false,
signed: false,
secure: false,
encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');
res.status(200).send({ status: 'ok', message: 'Success'});
});
}
else {
return res.status(401).send({ status: 'error', message: 'Invalid username/password combination. Please try again.' });
}
}
else {
return res.status(401).send({ status: 'error', message: 'Invalid username/password combination. Please try again.' });
}
}, err => {
return res.status(500).send({ status: 'error', message: 'unexpected error' });
});
}
这是客户端登录代码:
login(username, password) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: 'http://localhost:4001/api/users/login',
data: {
username,
password
}
}).then((res) => {
resolve(res.data);
}, (err) => {
reject(err);
});
});
}
服务器在端口 4001,React CRA 服务器在 3000
为了允许浏览器设置 cookie 并遵守同源策略,您的客户端代码应该查询 http://localhost:3000/api/users/login
(与客户端相同的主机)而不是(代理)服务器 url(端口 4001 ).
您还可以将基数 url 指定为 ${window.location.origin}/api
或仅 /api
.
根据 riwu 提到的 cookie 域应该匹配,在我的情况下设置 "cookieDomainRewrite": "localhost",
有效
下面是 React 中 setupProxy.js
的完整配置:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8000',
changeOrigin: true,
cookieDomainRewrite: "localhost",
})
);
};