Firebase 函数的 CORS 政策问题

Posted

技术标签:

【中文标题】Firebase 函数的 CORS 政策问题【英文标题】:CORS policies issues with Firebase functions 【发布时间】:2022-01-20 21:46:45 【问题描述】:

我在使用 Firebase 函数时遇到了 CORS 政策问题,即使我认为我在后端做的事情是正确的,我会向您展示代码。

const cors = require("cors");
const express = require("express");
const cookieParser = require('cookie-parser');
const app = express();
app.use(
    cors(
        origin: true,
        credentials: true
    ),
    cookieParser(),
);

这是我试图从前端调用的函数:

app.post("/auth/login", (req, res) => login(req, res));

有了这个身体:

const login = async (req, res) => 
  try 
    const user = 
      id: req.body.id,
      password: req.body.password,
    ;

    const auth = getAuth();

    const  valid, errors  = validateLoginData(user);

    if (!valid)
      throw  code: "validation-failed", message: errors, status: 400 ;

    let data = await signInWithEmailAndPassword(auth, user.id, user.password);
    let token = await data.user.getIdToken();

    console.log("TOKEN: " + token);

    res.cookie("_token", token,  httpOnly: true, maxAge: 3600000 );

    return res.status(202).json( message: "OK" );
   catch (err) 
    switch (err.code) 
      case "validation-failed":
        return res.status(err.status).json( message: err.message );

      case "auth/user-not-found":
      case "auth/wrong-password":
        return res
          .status(401)
          .json( message: "Wrong credentials, please try again" );

      default:
        return res.status(500).json( message: err.message );
    
  
;

所以问题来了:当我从邮递员调用它时它可以工作,当我从我的浏览器调用它时(勇敢)它不起作用并且它在控制台中告诉我这个:

Access to XMLHttpRequest at 'https://europe-west1-stormtestfordota.cloudfunctions.net/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

我已经尝试了许多我在网上找到的修复方法,但没有一个有效,请您帮帮我吗?

【问题讨论】:

不管您遇到什么问题,您是否了解像在此处那样允许任何具有凭据的来源的严重安全隐患? 是的!但是我们设置了安全规则来防止任何恶意行为 如何保护用户免受跨域请求伪造? 我们只使用 http cookie 以确保一切正常 HttpOnly cookie 属性对 CSRF 攻击没有任何作用...请重新考虑您的 CORS 配置并了解您在做什么。 【参考方案1】:

CORS 是一个 node.js 包,用于提供可用于enable CORS with various options 的 Express 中间件。

启用所有 CORS 请求 为单个路由启用 CORS 配置 CORS 使用动态来源配置 CORS 启用 CORS 预检 异步启用 CORS

如果你想像这样使用 Express 和 CORS 中间件,you should try onRequest functions 如下所示:

const express = require('express');
const cors = require('cors'); 
const app = express(); // Automatically allow cross-origin requests 
app.use(cors( origin: true )); // build multiple CRUD interfaces:
app.get('/test2', (req, res) =>  //Handle your test2 methods here
return res.send('your response') 
); // Expose Express API as a single Cloud Function: 
exports.api = functions.https.onRequest(app);
 

现在在这种情况下,您编写的 CORS 中间件将运行。您的函数的 URL 可能类似于 - https://us-central1-myapp.cloudfunctions.net/api 然后使用 /test2 路由它变为 https://us-central1-myapp.cloudfunctions.net/api/test2. CORS 在这里不再是问题,但请注意它现在是一个快速应用程序,因此函数中的参数是请求,响应而不是数据,上下文。

还可以尝试按照https://cloud.google.com/functions/docs/samples/functions-http-cors#functions_http_cors-nodejs 中列出的步骤进行操作,该功能将类似于this 中的以下内容

exports.hello = functions.https.onRequest((request, response) => 
response.set('Access-Control-Allow-Origin', '*'); 
response.set('Access-Control-Allow-Credentials', 'true'); // vital 
if (request.method === 'OPTIONS')  // Send response to OPTIONS requests
response.set('Access-Control-Allow-Methods', 'GET'); 
response.set('Access-Control-Allow-Headers', 'Content-Type'); 
response.set('Access-Control-Max-Age', '3600'); 
response.status(204).send(''); 
 
else 
 const params = request.body; 
const html = 'some html'; 
response.send(html)
  );

还有这个essential reading on CORS 以便更好地理解问题。

【讨论】:

以上是关于Firebase 函数的 CORS 政策问题的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 可调用函数 + CORS

从被 CORS 阻止的 Firebase 托管代码调用 Firebase 函数

如何在firebase函数中将参数传递给cors

为啥一个 Firebase 函数被 CORS 阻止了?

在 firebase 函数中启用 CORS

如何在 firebase 函数环境中解决 CORS?