即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie [英] Nodejs won't set cookie for React CRA application even with proxy

查看:36
本文介绍了即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 nodejs/express + React CRA 应用程序,我正在尝试从 nodejs 设置 cookie.服务器在端口 4001 上,因此在我的 React 应用程序的 project.json 中,我设置了 "proxy": "http://localhost:4001",但是 cookie 仍然不会在浏览器.

I have a nodejs/express + React CRA application, and I'm trying to set a cookie from nodejs. The server is on port 4001, so in my React application's project.json I have "proxy": "http://localhost:4001" set, but the cookie still won't get set in the browser.

我也在生产模式下对其进行了测试,React 应用程序直接从 nodejs 提供服务,并且在那里一切正常.

I've tested it in production mode as well, with the React application being served from nodejs directly and it all works fine there.

这是我设置 cookie 的方式.我在这里尝试了几种不同的选项组合,结果都一样.

Here is how I am setting the cookie. I've tried several different combinations of options here and they all have the same result.

res.cookie('jwt', token, {
    httpOnly: false,
    sameSite: false,
    signed: false,
    secure: false,
    encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');

在客户端,我使用 Axios 处理我的 ajax 请求.

On the client side I am using Axios for my ajax requests.

这里是登录的端点函数(POST/api/users/login):

Here is the endpoint function for login (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 上

Server is on port 4001, React CRA server is on 3000

推荐答案

要允许浏览器设置 cookie 并遵守同源策略,您的客户端代码应查询 http://localhost:3000/api/users/login(与客户端相同的主机)而不是(代理的)服务器 URL(端口 4001).

To allow the browser to set cookies and adhere to Same Origin Policy, your client code should query http://localhost:3000/api/users/login (same host as client) instead of the (proxied) server url (port 4001).

您还可以将基本 url 指定为 ${window.location.origin}/api 或仅指定 /api.

You can also specify the base url as ${window.location.origin}/api or just /api.

这篇关于即使使用代理,Nodejs 也不会为 React CRA 应用程序设置 cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆