Search code examples
corsexpress-gateway

Express Gateway CORS + apiKey authorization 401 Unauthorized


Intention

The CORS configuration seems to be valid and works, in a React-App I can easily access the gateway. Access via Postman is also possible, so the apiKey can't cause the problem.

But if I add authentication with apiKey, I get error messages in all browsers. In Chrome:

Issue

OPTIONS https://example-gateway.com/test 401 (Unauthorized)

Access to XMLHttpRequest at 'https://example-gateway.com/test' from origin 'https://example-app.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

What causes this behavior? Does the browser not send the required apiKey with the OPTIONS-CORS request and is therefore blocked?

How can this be solved?

Code

pipelines:
  adminAPI:
    apiEndpoints:
      - testApi
    policies:
      - cors:
          - action:
              origin: [https://example-gateway.com]
              methods: GET,POST,PUT,DELETE,OPTIONS
              preflightContinue: true
              optionsSuccessStatus: 204
              credentials: true
              maxAge: 600
              allowedHeaders:
                - Authorization
              exposedHeaders:
                - Authorization
      - key-auth:
          - action:
              apiKeyHeader: Authorization
              disableHeadersScheme: false
      - proxy:
          - action:
              serviceEndpoint: testBackend

Solution

  • I think the problem is that the key-auth is returning 401 for the OPTION call for CORS, which is the reason why probably you're receiving such problem.

    Most likely you'll be able to resolve this by adding a condition on the key-auth call.

    http:
      port: ${EG_HTTP_PORT:-8080}
    # https:
    #   port: 9999
    #   tls: {}
    admin: # remove this section to disable admin API
      port: 9876
      host: localhost # use 0.0.0.0 to listen on all IPv4 interfaces
    apiEndpoints:
      api:
        host: '*'
    serviceEndpoints:
      backend:
        url: 'http://localhost:9876' # btw this is EG admin API
    policies:
      - proxy
      - key-auth
      - cors
    pipelines:
      adminAPI:
        apiEndpoints:
          - api
        policies:
          - cors:
          - key-auth:
            - condition:
                name: not
                condition:
                  name: method
                  methods:
                    - OPTIONS
            action:
              apiKeyHeader: Authorization
              disableHeadersScheme: false
          - proxy:
              action:
                serviceEndpoint: backend