即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie
Posted
技术标签:
【中文标题】即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie【英文标题】:Nodejs won't set cookie for React CRA application even with proxy 【发布时间】:2019-04-19 18:53:55 【问题描述】:我有一个 nodejs/express + React CRA 应用程序,我正在尝试从 nodejs 设置一个 cookie。服务器在端口 4001 上,所以在我的 React 应用程序的 project.json 中我设置了 "proxy": "http://localhost:4001"
,但浏览器中仍然不会设置 cookie。
我也在生产模式下对其进行了测试,直接从 nodejs 提供 React 应用程序,并且一切正常。
这是我设置 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
【问题讨论】:
如果您只是想验证 express 设置的 cookie,请创建一个minimal reproducible example - 使用单个 app.get 和 cookie 管理设置 express 服务器不需要很多代码。 @Mike'Pomax'Kamermans 我不确定这是否有必要。正如我所说,当客户端和服务器在同一个端口上时,它在生产模式下工作,所以我的服务器端身份验证代码应该已经正确。然而,在开发模式下,React CRA 在自己的服务器上为客户端提供服务。因此,为了在开发中不引起跨域问题,React CRA 具有设置“代理”服务器以将请求转发到的功能。我怀疑是那个功能不能正常工作。 如果您认为没有必要,有必要。这是你做的事情,因为在形成那个 mcve 时,你通常会自己发现问题,因为如果你删除了足够的代码,你必须找到问题才能达到它消失的地步。 mcve 不只是“让我们帮助您”,它们是您在自己的调试过程中应该做的必要工作,而且几乎总是在这样做的过程中,您最终会自己发现并修复问题,即使您已经有了 SO写的帖子。 @Mike'Pomax'Kamermans 好的,我明白你的意思了,我会做一个完整的例子。与此同时,我用我的端点代码和客户端请求代码编辑了我的原始答案,看看是否有帮助。 【参考方案1】:根据 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",
)
);
;
【讨论】:
【参考方案2】:要允许浏览器设置 cookie 并遵守同源策略,您的客户端代码应查询 http://localhost:3000/api/users/login
(与客户端相同的主机)而不是(代理)服务器 url(端口 4001)。
您还可以将基本 url 指定为 $window.location.origin/api
或只是 /api
。
【讨论】:
以上是关于即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie的主要内容,如果未能解决你的问题,请参考以下文章
text 反向代理使用后端NodeJS Express创建React App Build
即使在发送消息后,也不会在 React 应用程序中触发 Firebase 云消息传递 onMessage
即使 DB 已正确更新,React UI 也不会在单击时重新呈现。第二次点击后,UI 重新渲染
React.memo prevProps 总是与 nextProps 不同,即使 props 永远不会改变