skip to Main Content

NEW EDIT: Got the function on the same domain so preflight check is passed. Now I funnily enough encounter auth issues. request is not authenticated …

My new request code on front-end:

key= "myworkingkey"
const response = await axios.post(
        '/functionName',
        { user_input: userInput },
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${key}`,
          },
        }
      );

Prev edit: This fetch needs and authorization which I’ve gotten to work. Only issue remaining is CORS … I’ve tried to set up wildcard config, which didn’t work. Right now, the error code I get is preflight response not successful 403. This leads me to believe that there are two possibilities.

1. CORS error is a mask for something else thanks to the people in the comments. Whenever I deploy my cloud function, I see memory limit of 256Mi exceeded error in the google cloud logs. How can I reduce this?

What I’m thinking: 2. This is a CORS issue, then how do I correctly handle the preflight response in my flask app/google cloud function. I realised I can’t pass the preflight response check since it sends it without an auth header. So to bypass this I need my function to be on the same domain as my front-end. Seems easy enough, but can’t get it to work …

firebase.json:

{
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/functionName",
        "function": "functionName"
      }
    ]

  },
  "functions": [
    {
      "source": "functions",
      "codebase": "default",
      "ignore": [
        "venv",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log"
      ],
      "name": "functionName"
    }
  ]
}

————————_

Error:

Access to fetch at ‘https://example-uc.a.run.app/’ from origin ‘https://example.web.app’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

I’m using a create-react-app hosted on firebase as my front-end and hosted my back-end on firebase functions in python.

here’s my fetch from the front-end side

const sendMessage = async () => {
    try {
        ...
        const response = await fetch('https://example-uc.a.run.app', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ user_input: userInput }),
      });
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
  
      const data = await response.json();
    } catch (error) {
      console.error('Error sending message:', error);
    }
};

here are parts of my main.py:

from firebase_admin import initialize_app
from firebase_functions import https_fn, options
from flask import Flask, jsonify
initialize_app()

app = Flask(__name__)



@https_fn.on_request(
    cors=options.CorsOptions(
        cors_origins=["https://example.web.app"],
        cors_methods=["GET", "POST", "OPTIONS"],
    )
)
def chat(req: https_fn.Request) -> https_fn.Response:
    headers = {
        'Access-Control-Allow-Origin': 'https://example.web.app',
        'Access-Control-Allow-Headers': 'Content-Type',
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
        'Access-Control-Max-Age': '3600',
    }
    if req.method == 'OPTIONS':
        return ('', 204, headers)

    ...
   
    return (jsonify(response_data), 200, headers)

I’ve tried handling it with chatGPT for 4 hours but won’t resolve this at all. tried all sorts of solutions ranging in how explicit they are. I’m probably misunderstanding something basic and overlooking an easy solution. Please help.

Tried using CORS(app)
tried setting up the Access-Control-Allow-Origin to *
tried passing recourses in the CORS arguments: CORS(app, resources={r"/": {"origins": "https://example.web.app"}})

if I remove the header in my fetch then I get CORS error 403

nothing solved the CORS policy error from appearing which prohibits me from fetching from my own back-end.

I stil want this to be secure and not ditch all security measures.

also if someone sees security issues in the way I’m doing this right now, please help me if I need to add some auth in the fetch or something.

2

Answers


  1. Chosen as BEST ANSWER

    CORS SOLVED: There were different parts at play here.

    I'm using firebase for everything here. I did not pass the preflight check since I was using the url firebase gave me on my front-end. I changed my firebase json to rewrite everything of /functionName to the correct function.

    firebase.json:

    {
      "hosting": {
        "public": "build",
        "ignore": [
          "firebase.json",
          "**/.*",
          "**/node_modules/**"
        ],
        "rewrites": [
          {
            "source": "/functionName",
            "function": "functionName"
          }
        ]
    
      },
      "functions": [
        {
          "source": "functions",
          "codebase": "default",
          "ignore": [
            "venv",
            ".git",
            "firebase-debug.log",
            "firebase-debug.*.log"
          ],
          "name": "functionName"
        }
      ]
    }
    

    Then I had auth issues as well ...

    To fix that temporarily, I followed this doc

    Don't know how to make this for production environment though ... here's my front-end call:

    const response = await axios.post(
                '/functionName',
                { user_input: userInput },
                {
                  headers: {
                    'Content-Type': 'application/json',
                    Authorization: `Bearer ${identityToken}`,
                  },
                }
              );
    

    and my main.py:

    @https_fn.on_request()
    def chat(req: https_fn.Request) -> https_fn.Response:
        if req.method == 'OPTIONS':
            headers = {
                'Access-Control-Allow-Origin': 'https://example.web.app',
                'Access-Control-Allow-Methods': 'POST, GET, OPTIONS', 
                'Access-Control-Allow-Headers': 'Content-Type', 
                'Access-Control-Max-Age': '3600',
            }
            return ('', 204, headers)
        headers = {
                'Access-Control-Allow-Origin': 'https://example.web.app',
            }
    
        try:  
    
            response_data = {...}
    
            return (jsonify(response_data), 200, headers)
        except:
            return ("Something went wrong processing", 400, headers)
        finally: 
            print('everything went great')
    
    
    

  2. Wildcards in CORS Headers:

    headers = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': 'Content-Type',
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
        'Access-Control-Max-Age': '3600',
    }
    

    Explicitly Set the Mode in Fetch:

    const response = await fetch('https://example-uc.a.run.app', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({ user_input: userInput }),
        mode: 'cors',
    });
    

    Security Considerations:

    'Access-Control-Allow-Origin': 'https://example.web.app',
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search