enabling CORS Google Cloud Function (Python)
Asked Answered
U

6

8

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.

Unthankful answered 25/9, 2020 at 20:4 Comment(0)
E
12

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.

Estis answered 25/9, 2020 at 21:59 Comment(5)
thanks! How would I implement this into my cloud function though? Do I call this function within my function that I actually want to run? def predict(request): cors_enabled_function(request) # do the rest of my function Unthankful
The snippet here is a Cloud Function (note that it takes a request parameter). You should add these lines at the top of your function.Estis
@DustinIngram, does this solution work if the function required authentication? I mean, must the OPTIONS request add the security header or not?Watkin
hi @mdev, I have the same problem as you. How to I integrate this to my cloud function? I get the request, but how to I add this to the request? Did you figure this out?Iceland
That docs example has never worked for me. Not in my apps or in JSFiddle. I think it's missing something.Ealasaid
T
4

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
Temperate answered 24/3, 2021 at 17:50 Comment(0)
Y
4

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)
Yelmene answered 11/6, 2021 at 8:18 Comment(0)
F
3

@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.

Feathering answered 16/3, 2021 at 10:44 Comment(1)
Sometimes a hero as to live without credits. This did the trick for me! Should be explained more clear in all documentation.Zosi
S
2

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!")
Swordtail answered 27/2 at 21:42 Comment(0)
P
1

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

Paginal answered 15/7, 2023 at 8:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.