# CORS

If you are having trouble authenticating with your application from an SPA that executes on a separate subdomain, you have likely misconfigured your CORS (Cross-Origin Resource Sharing) or session cookie settings.

> For more information on CORS and CORS headers, please consult the [MDN web documentation on CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#The_HTTP_response_headers).

You should ensure that your application's CORS configuration is returning the `Access-Control-Allow-Credentials` header with a value of `true` by setting the `AllowCredentials` option within your cors middleware configuration to `true`.

In addition, you should enable the `withCredentials` option on your global [axios](https://github.com/axios/axios) instance:

```js
axios.defaults.withCredentials = true;
```

## Using the `CORS` middleware

In this section you will learn how to use this middleware to allow cross-origin resource sharing.

The CORS middleware source code is located at [iris-contrib/middleware](https://github.com/iris-contrib/middleware/tree/master/cors) repository.

**1.** Install the middleware:

```sh
$ go get github.com/iris-contrib/middleware/jwt@master
```

**2.** Import in your code:

```go
import "github.com/iris-contrib/middleware/cors"
```

**3.** Initialize and configurate the middleware:

```go
crs := cors.New(cors.Options{
    AllowedOrigins:   []string{"*"},
    AllowCredentials: true,
})
```

**4.** Register the middleware:

```go
app.UseRouter(crs)
```

That's all. Your Iris web server can now accept cross-origin API requests from your client.

Example of a raw Javascript Client:

```js
// Replace the "host" with your Iris web server's domain.
const host = 'https://e1de7bc1.ngrok.io';

async function postData(url = '', data = {}) {
    const response = await fetch(url, {
        method: 'POST',
        mode: 'cors',
        cache: 'no-cache',
        credentials: 'same-origin',
        headers: {
            'Content-Type': 'application/json'
        },
        redirect: 'follow',
        referrerPolicy: 'no-referrer',
        body: JSON.stringify(data)
    });
    return response.json();
}

postData(host + '/api/mailer', {
        email: "me@test.com"
    })
    .then(data => {
        console.log(data);
        document.write(data.message);
    });
```

> Full example code can be found at: [iris-contrib/middleware/cors/\_example](https://github.com/iris-contrib/middleware/tree/master/cors/_example).

## The `CORS` Configuration

The full configuration of the `cors.Options` struct looks like this:

```go
// AllowedOrigins is a list of origins a cross-domain
// request can be executed from.
// If the special "*" value is present in the list,
// all origins will be allowed.
// An origin may contain a wildcard (*) to replace 0
// or more characters (i.e.: http://*.domain.com).
// Usage of wildcards implies a small performance penalty.
// Only one wildcard can be used per origin.
// Default value is ["*"].
AllowedOrigins []string

// AllowOriginFunc is a custom function to validate the origin.
// It takes the origin as argument and returns true if allowed
// or false otherwise. If this option is
// set, the content of AllowedOrigins is ignored.
AllowOriginFunc func(origin string) bool

// AllowedMethods is a list of methods the
// client is allowed to use with cross-domain requests.
// Default value is simple methods (HEAD, GET and POST).
AllowedMethods []string

// AllowedHeaders is list of non simple headers
// the client is allowed to use with
// cross-domain requests.
// If the special "*" value is present in the list,
// all headers will be allowed.
// Default value is [] but "Origin" is always
// appended to the list.
AllowedHeaders []string

// ExposedHeaders indicates which headers are safe to
// expose to the API of a CORS API specification.
ExposedHeaders []string

// MaxAge indicates how long (in seconds) the results
// of a preflight request can be cached.
MaxAge int

// AllowCredentials indicates whether the request
// can include user credentials like
// cookies, HTTP authentication
// or client side SSL certificates.
AllowCredentials bool

// OptionsPassthrough instructs preflight to
// let other potential next handlers to
// process the OPTIONS method. Turn this on
// if your application handles OPTIONS.
OptionsPassthrough bool

// Debugging flag adds additional output to
// debug server side CORS issues.
Debug bool
```

## Do it yourself

You can always use the Iris request Context to manually send the necessary headers to handle preflight and therefore allow cross-origin requests.

Here is a simple example:

```go
package main

import "github.com/kataras/iris/v12"

func main() {
	app := iris.New()

    // Our custom CORS middleware.
	crs := func(ctx iris.Context) {
		ctx.Header("Access-Control-Allow-Origin", "*")
		ctx.Header("Access-Control-Allow-Credentials", "true")

		if ctx.Method() == iris.MethodOptions {
            ctx.Header("Access-Control-Methods",
                "POST, PUT, PATCH, DELETE")

            ctx.Header("Access-Control-Allow-Headers",
                "Access-Control-Allow-Origin,Content-Type")

            ctx.Header("Access-Control-Max-Age",
                "86400")

			ctx.StatusCode(iris.StatusNoContent)
			return
		}

		ctx.Next()
	}

    app.UseRouter(crs)
    
    // [register routes...]
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://iris-go.gitbook.io/iris/security/cors.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
