Case Study Jobteaser Case Study: Scalable Public APIs with KrakenD

Document updated on Jun 27, 2023

Cross-Origin Resource Sharing (CORS) Configuration

When KrakenD endpoints are consumed from a browser, you should enable the Cross-Origin Resource Sharing (CORS) module, as browsers restrict cross-origin HTTP requests initiated from scripts.

When the Cross-Origin Resource Sharing (CORS) configuration is enabled, KrakenD uses additional HTTP headers to tell browsers that they can use resources from a different origin (domain, protocol, or port). For instance, you will need this configuration if your web page is hosted at https://www.domain.com and the Javascript references the KrakenD API at https://api.domain.com.

Configuration

CORS configuration lives in the root of the file, as it’s a service component. Add the namespace security/cors under the global extra_config as follows:

{
  "version": 3,
  "extra_config": {
    "security/cors": {
      "allow_origins": [
        "*"
      ],
      "allow_methods": [
        "GET",
        "HEAD",
        "POST"
      ],
      "expose_headers": [
        "Content-Length",
        "Content-Type"
      ],
      "allow_headers": [
        "Accept-Language"
      ],
      "max_age": "12h",
      "allow_credentials": false,
      "debug": false
    }
  }
}

The configuration options of this component are as follows:

Fields of HTTP Security
* required fields

allow_credentials boolean
When requests can include user credentials like cookies, HTTP authentication or client side SSL certificates.
Defaults to false
allow_headers array
An array with the headers allowed, but Originis always appended to the list. Requests with headers not in this list are rejected.
Defaults to []
allow_methods array
An array with all the HTTP methods allowed, in uppercase. Possible values are GET, HEAD,POST,PUT,PATCH,DELETE, or OPTIONS
Defaults to ["GET","HEAD","POST"]
allow_origins array
An array with all the origins allowed, examples of values are https://example.com, or * (any origin).
Defaults to ["*"]
allow_private_network boolean
Indicates whether to accept cross-origin requests over a private network.
Defaults to false
debug boolean
Show debugging information in the logger, use it only during development.
Defaults to false
expose_headers array
List of headers that are safe to expose to the API of a CORS API specification.
Defaults to ["Content-Length","Content-Type"]
max_age string
For how long the response can be cached. For zero values the Access-Control-Max-Age header is not set.
Specify units using ns (nanoseconds), us or µs (microseconds), ms (milliseconds), s (seconds), m (minutes), or h (hours).
Defaults to "0h"
options_passthrough boolean
Instructs preflight to let other potential next handlers to process the OPTIONS method. Turn this on when you set the auto_opts flag in the router to true.
Defaults to false
options_success_status integer
The HTTP status code that is considered a success.
Example: 200
Defaults to 204
Allow credentials and wildcards
According to the CORS specification, you are not allowed to use wildcards and credentials at the same time. If you need to do this, check this workaround

Debugging configuration

The following configuration might help you debug your CORS configuration. Check the inline @comments:

{
  "endpoints":[
        {
            "@comment": "this will fail due to double CORS validation",
            "endpoint":"/cors/no-op",
            "input_headers":["*"],
            "output_encoding": "no-op",
            "backend":[
                {
                    "url_pattern": "/__debug/cors",
                    "host": ["http://localhost:8080"],
                    "encoding": "no-op"
                }
            ]
        },
        {
            "@comment": "this won't fail because CORS preflight headers are removed from the request to the backend",
            "endpoint":"/cors/no-op/martian",
            "input_headers":["*"],
            "output_encoding": "no-op",
            "backend":[
                {
                    "url_pattern": "/__debug/cors/martian",
                    "host": ["http://localhost:8080"],
                    "encoding": "no-op",
                    "extra_config":{
                      "modifier/martian": {
                          "fifo.Group": {
                              "scope": ["request", "response"],
                              "aggregateErrors": true,
                              "modifiers": [
                                  {
                                    "header.Blacklist": {
                                      "scope": ["request"],
                                      "names": [
                                        "Access-Control-Request-Method",
                                        "Sec-Fetch-Dest",
                                        "Sec-Fetch-Mode",
                                        "Sec-Fetch-Site",
                                        "Origin"
                                      ]
                                    }
                                  }
                              ]
                          }
                      }
                    }
                }
            ]
        },
        {
            "@comment": "this won't fail because no headers are added to the request to the backend",
            "endpoint":"/cors/no-op/no-headers",
            "output_encoding": "no-op",
            "backend":[
                {
                    "url_pattern": "/__debug/cors/no-headers",
                    "host": ["http://localhost:8080"],
                    "encoding": "no-op"
                }
            ]
        }
]}

Adding the OPTIONS method

When working in a SPA, you will usually receive OPTIONS calls to KrakenD; although this configuration is not related to CORS, it usually goes in hand.

To support OPTIONS in your endpoints, you only need to add the flag auto_options as follows:

{
  "version": 3,
  "extra_config": {
    "router": {
       "auto_options": true
    },
    "security/cors": {
      "@comment": "...CORS configuration inside this block..."
    }
  }
}
Fields of "router"
* required fields

auto_options boolean
When true, enables the autogenerated OPTIONS endpoint for all the registered paths
Scarf

Unresolved issues?

The documentation is only a piece of the help you can get! Whether you are looking for Open Source or Enterprise support, see more support channels that can help you.

See all support channels