# Configure CORS

Cross-Origin Resource Sharing (CORS) is a security mechanism that allows web browsers to make requests to a domain different from the one that served the original web page. The [`cors`](https://docs.api7.ai/hub/cors.md) plugin simplifies this by handling the necessary headers on the Gateway.

Use this guide for the common CORS workflows. For the full plugin field reference, regex matching, and plugin metadata options, see [`cors`](https://docs.api7.ai/hub/cors.md).

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

* An API7 Enterprise instance is running.
* A Gateway Group is created and a Gateway instance is running.
* A [token from the Dashboard](https://docs.api7.ai/api7-gateway/reference/obtain-dashboard-token.md).

## Configure Basic CORS[​](#configure-basic-cors "Direct link to Configure Basic CORS")

The following configuration allows requests from any origin with default methods and headers.

* Admin API
* ADC

```
curl -k "https://localhost:7443/apisix/admin/services/cors-service?gateway_group_id={gateway_group_id}" -X PUT \

  -H "X-API-KEY: ${API_KEY}" \

  -H "Content-Type: application/json" \

  -d '{

    "name": "cors-service",

    "upstream": {

      "type": "roundrobin",

      "scheme": "http",

      "nodes": [

        {

          "host": "httpbin.org",

          "port": 80,

          "weight": 100

        }

      ]

    }

  }'



curl -k "https://localhost:7443/apisix/admin/routes/cors-route?gateway_group_id={gateway_group_id}" -X PUT \

  -H "X-API-KEY: ${API_KEY}" \

  -H "Content-Type: application/json" \

  -d '{

    "name": "cors-route",

    "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],

    "paths": ["/cors"],

    "service_id": "cors-service",

    "plugins": {

      "proxy-rewrite": {

        "uri": "/get"

      },

      "cors": {

        "allow_origins": "*",

        "allow_methods": "GET,POST,PUT,DELETE,OPTIONS",

        "allow_headers": "*",

        "max_age": 3600

      }

    }

  }'
```

adc.yaml

```
services:

  - name: cors-service

    upstream:

      nodes:

        - host: httpbin.org

          port: 80

          weight: 1

    routes:

      - name: cors-route

        uris:

          - /cors

        methods:

          - GET

          - POST

          - PUT

          - DELETE

          - OPTIONS

        plugins:

          proxy-rewrite:

            uri: /get

          cors:

            allow_origins: "*"

            allow_methods: "GET,POST,PUT,DELETE,OPTIONS"

            allow_headers: "*"

            max_age: 3600

    labels:

      docs-example: cors-service
```

Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:

```
adc diff -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=cors-service
```

Synchronize the reviewed configuration:

```
adc sync -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=cors-service
```

## Configure Secure CORS with Credentials[​](#configure-secure-cors-with-credentials "Direct link to Configure Secure CORS with Credentials")

To allow credentials such as cookies or authorization headers, you must specify the allowed origins and set `allow_credential` to `true`.

* Admin API
* ADC

```
curl -k "https://localhost:7443/apisix/admin/services/credentialed-cors-service?gateway_group_id={gateway_group_id}" -X PUT \

  -H "X-API-KEY: ${API_KEY}" \

  -H "Content-Type: application/json" \

  -d '{

    "name": "credentialed-cors-service",

    "upstream": {

      "type": "roundrobin",

      "scheme": "http",

      "nodes": [

        {

          "host": "httpbin.org",

          "port": 80,

          "weight": 100

        }

      ]

    }

  }'



curl -k "https://localhost:7443/apisix/admin/routes/credentialed-cors-route?gateway_group_id={gateway_group_id}" -X PUT \

  -H "X-API-KEY: ${API_KEY}" \

  -H "Content-Type: application/json" \

  -d '{

    "name": "credentialed-cors-route",

    "methods": ["GET", "POST", "OPTIONS"],

    "paths": ["/credentialed-cors"],

    "service_id": "credentialed-cors-service",

    "plugins": {

      "proxy-rewrite": {

        "uri": "/get"

      },

      "cors": {

        "allow_origins": "https://example.com,https://api.example.com",

        "allow_methods": "GET,POST",

        "allow_credential": true,

        "expose_headers": "X-Custom-Header",

        "max_age": 600

      }

    }

  }'
```

adc.yaml

```
services:

  - name: credentialed-cors-service

    upstream:

      nodes:

        - host: httpbin.org

          port: 80

          weight: 1

    routes:

      - name: credentialed-cors-route

        uris:

          - /credentialed-cors

        methods:

          - GET

          - POST

          - OPTIONS

        plugins:

          proxy-rewrite:

            uri: /get

          cors:

            allow_origins: "https://example.com,https://api.example.com"

            allow_methods: "GET,POST"

            allow_credential: true

            expose_headers: "X-Custom-Header"

            max_age: 600

    labels:

      docs-example: credentialed-cors-service
```

Preview the changes owned by this example and confirm that the diff contains no unintended updates or deletions:

```
adc diff -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=credentialed-cors-service
```

Synchronize the reviewed configuration:

```
adc sync -f adc.yaml \

  --include-resource-type service \

  --label-selector docs-example=credentialed-cors-service
```

## Validate the Configuration[​](#validate-the-configuration "Direct link to Validate the Configuration")

Verify the wildcard policy with a preflight request:

```
curl -i -X OPTIONS "http://127.0.0.1:9080/cors" \

  -H "Origin: https://example.com" \

  -H "Access-Control-Request-Method: POST"
```

Then verify the credentialed policy on its separate route:

```
curl -i -X OPTIONS "http://127.0.0.1:9080/credentialed-cors" \

  -H "Origin: https://example.com" \

  -H "Access-Control-Request-Method: POST"
```

Each response should include the `Access-Control-Allow-Origin` and `Access-Control-Allow-Methods` values from its route. The credentialed route should also return `Access-Control-Allow-Credentials: true`.

If the route returns `404` immediately after you apply the configuration, wait a few seconds for the latest configuration to reach the gateway and retry.

## Next Steps[​](#next-steps "Direct link to Next Steps")

* [Inject Faults](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/fault-injection.md) — test your application resilience.
* [Configure Proxy Mirror](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/proxy-mirror.md) — duplicate traffic to a test environment.
* [Configure Rate Limiting](https://docs.api7.ai/api7-gateway/how-to-guides/traffic-management/rate-limiting.md) — protect your APIs from abuse.
