1

I have a CORS-enabled Spring Boot API that runs on Google Cloud Run and a Vue.js front end that runs on Firebase and uses Axios to make the calls to the back end.

The Problem is that when the front end wants to access the back end (Browser --> Google Clud), it fails with:

Access to XMLHttpRequest at 'https://<backend>' from origin 'https://<frontend>' 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.

  1. If I access from LOCAL front end (also Browser) to a LOCAL back end, it works: The error above is not shown in the Browser console and I get the data).
  2. If I make the OPTIONS or GET call from Postman to the Google Cloud back end, it works.

I noticed, that with Postman I need to include the Authorization header in the OPTIONS request to send the Bearer token to Google to make it work. The Browser does not send any Authorization header in the OPTIONS call, even if I add withCredentials: true to the Axios config like this:

const response = await axios({
      method: 'post',
      withCredentials: true,
      url: 'https://<backend>',
      headers: {
        'Authorization': 'Bearer ' + gCloudToken
      },
      data: {
        // data...
      }
    });
  1. Isn't that a security problem, to send the token in the header? I mean, everyone can see the headers and then fake a call to the server.
  2. Can anybody show how to send the Authorization header in the OPTIONS call via Axios or tell how to correctly handle this problem?

UPDATE 1:

The request from the browser looks like this:

OPTIONS /path/to/api HTTP/2
Host: <backend>-ew.a.run.app
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Referer: https://frontend.web.app/
Origin: https://frontend.web.app
Connection: keep-alive

And this is the response:

HTTP/2 403 Forbidden
date: Tue, 07 Jul 2020 23:57:27 GMT
content-type: text/html; charset=UTF-8
server: Google Frontend
content-length: 320
alt-svc: h3-29=":443"; ma=2592000,h3-27=":443"; ma=2592000,h3-25=":443"; ma=2592000,h3-T050=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
X-Firefox-Spdy: h2

As you can see, no CORS headers (like e.g. access-control-allow-origin) are present.

RichArt
  • 1,534
  • 18
  • 35
  • 2
    Could you tell us if cloud run is accepting unauthenticated calls( this you have set it when deploying) Share with us the Request you are creating? The token sent in the headers is not a big security issue because this tokens expire. – Soni Sol Jul 07 '20 at 18:29
  • @JoséSoní: I made the UPDATE 1 in my question. Cloud Run is NOT accepting unauthenticated calls. But yes, I will try it with unauthenticated calls and post the result. – RichArt Jul 08 '20 at 00:07

1 Answers1

1

The cause of this issue is that by not allowing unauthenticated calls the CORS preflight are always rejected with a 403 error message.

There is already a feature request for Cloud Run in orther to support CORS and authentication with Cloudrun.

The Workaround I would see so far is to allow unauthenticated calls on the CloudRun and implement the authentication on your code, However this can have security disadvantages.

Soni Sol
  • 2,367
  • 3
  • 12
  • 23