部署到 Vercel 后,cookie 未在请求标头中发送

问题描述 投票:0回答:1

我正在构建一个 MERN 博客应用程序。最初在部署到 vercel 之前运行良好。 服务器托管在 http://localhost:3000 上,客户端 React 部分托管在 http://localhost:8000 上。 服务器文件部署在 vercel 上。 其他路由工作正常,但需要 cookie(令牌)的路由无法工作。 当我在请求标头中看到时,cookie 没有被发送。但是当我在 vercel 上部署之前执行此操作时,它也会将 cookie 发送到后端。 为什么会出错?

后端的 vercel url 是: https://blog-app-server-red.vercel.app/

前端代码(反应):

const getProfilePic = async ()=>{
     try {
      const response = await fetch('https://blog-app-server-red.vercel.app/user/'+userId , {
        credentials : 'include',
        headers: {
          "Content-Type": "application/json",
          "Access-Control-Allow-Credentials": true,
        }
      })

后端代码(express、mongo):

app.get('/user/:id' , async (req, res)=>{
    try {
                const {token} = req.cookies;
                const {id} = req.params;
                if(token){
                    jwt.verify(token , process.env.JWT_KEY , {} , async (err , info)=>{
                        if(err){
                            throw "Wrong Token ! Access Denied"
                        }
                        const user = await User.findById(id).select('-password');
                        res.status(200).json(user);

                    });
                }
                else{
                    res.status(400).json({error : "Unauthorized !!!"})
                }
            } catch (error) {
                res.status(400).json({error});
            }
})

CORS 中间件(后端):

app.use(cors({credentials : true , origin : 'http://localhost:3000'}));

当对 http://localhost:8000 (后端 api)执行相同操作时,它工作正常并且 cookie 也正在发送。 这是为什么?

reactjs node.js mongodb cookies cors
1个回答
0
投票

当您的后端部署在 Vercel 上时,此问题似乎是由于 CORS 和 cookie 策略造成的。

尝试这些配置以确保 cookie 在服务器上正确发送,

const allowedOrigins = ['http://localhost:8000', 'https://your-frontend-domain.vercel.app'];

    app.use(cors({
        credentials: true,
        origin: (origin, callback) => {
            if (allowedOrigins.includes(origin) || !origin) {
                callback(null, true);
            } else {
                callback(new Error('Not allowed by CORS'));
            }
        }
    }));

确保后端服务器端点设置的 cookie 具有要在跨源请求中发送的适当属性。您需要将

SameSite
属性设置为
None
并确保将
Secure
属性设置为
true
以实现安全上下文 (HTTPS)

res.cookie('token', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'None'
});

在你的前端代码上一切看起来都不错,添加 try-catch 进行错误处理会很好。

const getProfilePic = async () => {
    try {
        const response = await fetch('https://blog-app-server-red.vercel.app/user/' + userId, {
            credentials: 'include',
            headers: {
                "Content-Type": "application/json",
                "Access-Control-Allow-Credentials": true,
            }
        });

        if (!response.ok) {
            throw new Error('Network response was not ok');
        }

        const data = await response.json();
        return data;
    } catch (error) {
        console.error('There was a problem with your fetch operation:', error);
    }
};

仅当您使用会话时,请确保会话配置允许跨域 cookie,

app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    cookie: {
        secure: true, // Ensure this is true if using HTTPS
        sameSite: 'None'
    }
}));

在生产中,您的前端和后端都应该通过 HTTPS 提供服务。通过非安全连接发送时,浏览器会阻止标记为

Secure
的 cookie。

使用浏览器的开发者工具验证 cookie 是否已正确设置和发送。检查“应用程序”>“Cookie”以确保令牌存储正确,并在“网络”>“标头”下检查 cookie 是否包含在请求中。

© www.soinside.com 2019 - 2024. All rights reserved.