0

I'm getting CORS errors in my Angular console when I call one of my Cloud Functions.

Access to fetch at 'https://us-central1-my-project.cloudfunctions.net/myFunction' from origin 'http://localhost:4200' 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.

Can I fix this by setting permissions in my Google Cloud Console? From your Dashboard, go to Resources, then Cloud Functions. From your list of Cloud Functions, click on the function, go to the PERMISSIONS tab, click GRANT ACCESS, then under Add principals type in allUsers, then under Assign roles select Cloud Functions and then Cloud Function Invoker and then SAVE.

Works great...except that now my Cloud Function is publicly accessible.

Instead of allUsers I put in http://localhost:4200/home, where my Angular project is running. That threw an error message:

Error: Email addresses and domains must be associated with an active Google Account, Google Workspace account, or Cloud Identity account.

I read the Firebase documentation Configure headers. This didn't work:

firebase.json

  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [ {
      "source": "/myCloudFunction",
      "headers": [ {
        "key": "Access-Control-Allow-Origin",
        "value": "*"
      } ]
    } ]
  },

And the many answers in this question didn't help because the answers are for onRequest Cloud Functions, not onCall Cloud Functions:

const cors = require('cors')({origin: true});

exports.fn = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        // your function body here - use the provided req and res from cors
    })
});

This Cloud Function has been working for months and today started throwing the CORS error. None of my other Cloud Functions are throwing CORS errors. I didn't make any changes to this Cloud Function. I switched from running the Cloud Functions in the Firebase Emulators to running in the Firebase cloud. I tried switching between httpsCallableFromURL and httpsCallable but this didn't help. Using httpsCallableFromURL fixed a CORS error a while ago in a different Cloud Function.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Thomas David Kehoe
  • 10,040
  • 14
  • 61
  • 100

1 Answers1

2

You absolutely need to have allUsers set on your function in order for it to be accessible by your web site. The Google Cloud permissions you're toying with are only useful if the client is authenticating with a service account or Google account and sending special headers along with the request, which is not the case here. If you need to protect your function from use, you should write code for that in the body of your function and check whatever form of authentication is being provided by the caller, which for callables, is going to be Firebase Auth. You can also use App Check to help the verification process, though it's not 100% accurate.

See also:

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Thanks for the fast response! I just tried `allAuthorizedUsers`, that didn't work. I set `allUsers` and it works. I'll look at the article you recommended. – Thomas David Kehoe Feb 11 '23 at 00:33