enabling CORS Google Cloud Function (Python)

6.5k views Asked by At

Can use you flask_cors in Google Cloud Functions?

app = Flask(__name__)
cors = CORS(app)

Locally this flask_cors package works but when deployed onto Cloud Functions it does not.

I have tried many different ways, as GCP has suggested https://cloud.google.com/functions/docs/writing/http but I am still getting that CORS error:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

6

There are 6 answers

5
Dustin Ingram On

No, the app variable is not available in Cloud Functions.

Instead you can manually handle CORS:

def cors_enabled_function(request):
    # For more information about CORS and CORS preflight requests, see
    # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
    # for more information.

    # Set CORS headers for the preflight request
    if request.method == 'OPTIONS':
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600'
        }

        return ('', 204, headers)

    # Set CORS headers for the main request
    headers = {
        'Access-Control-Allow-Origin': '*'
    }

    return ('Hello World!', 200, headers)

See https://cloud.google.com/functions/docs/writing/http#handling_cors_requests for more details.

0
Wes Chua On

There is no APP in cloud functions. You can set the CORS headers as stated in google cloud documentations and return your JSON as how you write in Flask.

The example below function called hello_world which is used for a post request. It return the status and headers of the CORS.

from flask import jsonify

def hello_world(request):
    request_json = request.get_json()
    # Set CORS headers for the preflight request
    if request.method == 'OPTIONS':
        # Allows GET requests from any origin with the Content-Type
        # header and caches preflight response for an 3600s
        headers = {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'POST',
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Max-Age': '3600'
        }

        return ('', 204, headers)

    # Set CORS headers for the main request
    headers = {
        'Access-Control-Allow-Methods': 'POST',
        'Access-Control-Allow-Origin': '*'
    }

   if request_json and 'labels' in request_json:
        # THIS IS THE PLACE YOU WRITE YOUR CODE.
        # AWLAYS RETURN WITH THE HEADERS AND STATUS
        return (jsonify({"ok": "Great Day 2"}), 200, headers)
0
Kishoreganesh Sundararajan On

If you are trying to make a Post request to your google cloud function from the front end and face an issue with CORS. The Following template must work. It worked for me...

#import all required packages
import json

def function_name(request):
    if request.method == 'OPTIONS':
        headers = {
            'Access-Control-Allow-Origin': '*',  # Allow your function to be called from any domain
            'Access-Control-Allow-Methods': 'POST',  # POST or any method type you need to call
            'Access-Control-Allow-Headers': 'Content-Type', 
            'Access-Control-Max-Age': '3600',
        }
        return ('', 204, headers)

    # Set CORS headers for main requests
    headers = {
        'Access-Control-Allow-Origin': '*',
    }

    # Your code logic goes here

    # Return your response
    return (json.dumps({'status': 'success'}), 200, headers)

If you also want to handle Auth in function after a preflight request refer to this discussion: https://github.com/FirebaseExtended/reactfire/discussions/483

1
cmartman On

@mdev, I had a similar issue and solved it by adding the CORS headers for the preflighted request at the beginning of my cors_enabled_function (as Dustin Ingram suggests); the CORS headers for the main request I left for the end of my function (this way including the response in the return statement, be it JSON, text, etc). In other words, I put my main function code in between the preflighted and main CORS requests.

0
SARose On

If you're using flask already then the easiest way is to use flask-cors

https://github.com/corydolphin/flask-cors

Decorate your cloud function like below and you're done.

from flask_cors import cross_origin

@cross_origin()
@json
def fun_function(request):
    # enter code here

Or you can add as much functionality as you need as shown below.

from flask_cors import cross_origin

@cross_origin(allowed_methods=['POST'])
@json
def fun_function(request):
    # enter code here
0
JeffD23 On

In Firebase Python Cloud Functions, it can be done like this:

from firebase_functions import https_fn, options

cors_settings = options.CorsOptions(cors_methods=["*"], cors_origins=["*"])

@https_fn.on_request(cors=cors_settings)
def cors_enabled_function(request):
    return https_fn.Response("cors enabled!")