Search code examples
google-cloud-platformgoogle-cloud-functionscorsfetch-apigoogle-iam

GCP Cloud Functions: Allow preflight request


I have a Cloud Function deployed in my GCP project. This Function uses GCP authentication to restrict access (so no unauthenticated user can call the function). When I'm trying to use fetch() from my browser to call this function, the browser first tries to send a preflight request, which omits the Authorization header.

I implemented CORS into my application with the help of this tutorial, but the preflight request never actually reaches this part of the code, since unauthenticated users can't reach the function. An obvious solution would be to allow any unauthenticated user to call the function and handle authentication from the function itself, but that would be added complexity, that I'd like to avoid.

Is there any way to let OPTIONS requests through, while keeping other request methods back?

Here's the code I used for setting the CORS headers:

res.set('Access-Control-Allow-Origin', '*');

  if (req.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    res.set('Access-Control-Allow-Methods', 'GET');
    res.set('Access-Control-Allow-Headers', 'Content-Type');
    res.set('Access-Control-Max-Age', '3600');
    res.status(204).send('');
  }

Solution

  • As John Hanley links to in the comments to the original question, you can customise IAP settings to allow http options requests. However, in order to do this you will need to enable IAP on your project and this means that all requests to your cloud functions will need to be signed.

    An alternative option is to change the invoke permissions on each of your cloud functions to give "allUsers" the role "cloudfunctions.invoker".

    You can do this manually within the GCP console: https://console.cloud.google.com/functions/list

    Or you can do it in the terminal with

    gcloud functions add-iam-policy-binding FUNCTION_NAME --member="allUsers" --role="roles/cloudfunctions.invoker" --region="YOUR_REGION(e.g. us-east1)"
    

    If you give allUsers invoke permission then you are letting anyone on the web call your cloud function so you will need to add appropriate authentication and security within your functions, such as adding suitable CORS checking.