Get hands-on experience with 20+ free Google Cloud products and $300 in free credit for new customers.

CORS issue with API gateway

hi,
I'm running into the CORS error and not able to hit the API gateway endpoint from the web app. CORS is enabled on the cloud run backend-api globally and tried for each route as well. Also, I went through the openapi docs regarding this issue and added appropriate configs to enable cors on the endpoint using x-google-endpoints config. Also, added the options route in the yaml as well. Still not working. I'm not able to figure out what I'm missing.  Is there anything I can check or try to resolve this issue? 

thank you.


0 3 7,186
3 REPLIES 3

Hello @hypotypo,

Welcome to the Google Cloud Community!

You can try the following troubleshooting options:

  1. Make sure that the x-google-endpoints follows the right configuration such as the correct naming format.
  2. Check out using ESPv2 startup flags to support CORS.
  3. You can also check out this Stack Overflow post as you might have the same case. Currently the API gateway does not have CORS support yet. However, there are workarounds in the post that might give you insights on how to solve the issue.
  4. There is also a guide in Connecting a webapp with CORs and Google API Gateway
  5. If the above options don't work, you can contact Google Cloud Support to further look into your case.

Let me know if it helped, thanks!

Here is what I have: 

  • Secure cloud run API 
  • firebase authentication
  • API gateway security configs for firebase authentication 

Here is config yaml for the api gateway. 

# openapi2-run.yaml
swagger: '2.0'
info:
  title: API Gateway + Cloud Run
  version: 1.0.0
schemes:
  - https
produces:
  - application/json
host: {api-gateway}.cloud.goog   #managed service url 
x-google-endpoints:
- name: {api-gateway}.cloud.goog
  allowCors: True
securityDefinitions:
  firebase:
    authorizationUrl: ''
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "https://securetoken.google.com/{proj-id}"
    x-google-audiences: "{cloud-run-api}-run.app"
    x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com"
paths:
  /one:
    post:
      security:
        - firebase: []
      description: 
      operationId: one
      x-google-backend:
        address: {cloud-run-api}-run.app/one
      responses:
        200:
          description: Success
          schema:
            type: string
        400:
          description: Bad request
          schema:
            type: object
            properties:
              error:
                type: string
                description: The error message
        500:
          description: Internal error
          schema:
            type: object
            properties:
              error:
                type: string
                description: The error message
    options:
      security:
        - firebase: []
      operationId: corsOne
      x-google-endpoints:
      - name: {api-gateway}.cloud.goog
        allowCors: True
      responses:
        200:
          description: "Allow"
        401:
          description: "Cors not allowed"

 I'm able to hit the gateway endpoint via rest client and pass the firebase token using authorization header. It does make a successful call to the cloud run endpoint. But it keeps failing pre-flight request from the web app and getting CORS error in the browser console. 

When I checked the gateway logs,  I'm seeing  jwt missing error, even though my web app is passing the authorization header with the token. 

response_code_detail: "jwt_authn_access_denied{Jwt_is_missing}"
service_agent: "ESPv2/2.44.0"

  Not sure what else I can do.

Did ever figure this out? I'm wondering if you have the server side settings set if allowCors is passing the responsiblity onto the backend if I'm understanding how that setting works.  I finally managed to return data to my React app by hitting a service in Cloud Run that calls into Firestore.

In my backend express api...

  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')

That said, the issue I'm having is getting the swagger editor (https://editor.swagger.io/) to generate the Swagger UI using my OpenAPI.yaml.  

For it to work In my React fetch I call the API Gateway's URL https://<theapigatewayurl>.uc.gateway.dev NOT the .cloud.goog managed endpoint address.

But the swagger is using the host value (.cloud.goog) managed service address as the generated endpoints request url which is probably right but when I change the host to use the uc.gateway.dev address, it breaks the React app with another CORS issue.

9/11/23 - Update.
I managed to get the past the last cors issue in the react app and use the uc.gateway.dev as the host address.  Followed the guide in step 4 of the above post. There's a github repo and a openapi.yaml file with "options:" section for each path and that seemed to fix it

Still can't seem to test the APIs from the swagger that is generated.  I'm using Firebase auth and the Swagger's Authorize button is asking for a "client_id" and don't see a way for me to enter the auth/bearer token so I'm just using Postman instead for now.