Skip to content

Cors ​

From Wikipedia, Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be accessed from another domain outside the domain from which the first resource was served.

What is CORS?

Cross-Origin Resource Sharing or CORS is a mechanism that allows browsers to request data from 3rd party URLs (or origins) and is a common pain point for web developers. Learn the basics of CORS in 100 seconds from Fireship.io.

Since CORS is a common pain point for web developers, Leaf provides a first-party integration that takes care of all the heavy lifting for you.

Setting Up ​

You can install the CORS module through the Leaf CLI or with composer.

bash
leaf install cors
bash
composer require leafs/cors

Enabling CORS ​

After installing the cors module, Leaf automatically links it to your app, so it can be used directly on the Leaf instance as the cors() method.

php
app()->cors();

// ... your app
php
$app = new Leaf\App();
$app->cors();

// ... your app

This will allow all users from any website to access your app, even if they are on a website you didn't explicitly allow. If you want to restrict access to your app, you can pass in an array of options to the cors() method.

php
app()->cors([
  'origin' => ['http://example.com', 'http://example.org'],
  'methods' => ['GET', 'POST'],
]);

This will only allow users from http://example.com and http://example.org to access your app using the GET and POST methods. You can find a list of all available options below.

If you want to allow access to all subdomains of a domain, you can use just the website domain as the origin without the http:// or https://.

php
app()->cors([
  'origin' => 'example.com',
]);

This will allow http://example.com, https://example.com, http://www.example.com, and https://some-subdomain.example.com to access your app. Of course, you can also use a regular expression to match multiple domains. You can find a full list of options below.

CORS + Leaf MVC ​

If you are using Leaf MVC, you can configure CORS using your environment variables in place of the configuration above:

.env
txt
CORS_ALLOWED_ORIGINS='/\.example\.com$/'
CORS_ALLOWED_METHODS='GET,HEAD,PUT,PATCH,POST,DELETE'
CORS_ALLOWED_HEADERS='*'

While this is easier and allows you to easily configure different environments, it can sometimes be limiting for example when you want to return a function for dynamically set your allowed origins. For this reason, you can publish your CORS configuration using the command below:

bash
php leaf config:publish cors

This will create or update your CORS config in config/cors.php. You can then use the options below to configure the CORS module to suit your exact needs.

Configuration Options ​

The cors() method takes in an array of options. Here are the available options:

  • origin: Configures the Access-Control-Allow-Origin CORS header. Possible values:

    • String - set origin to a specific origin. For example if you set it to "http://example.com" only requests from "http://example.com" will be allowed.
    • RegExp - set origin to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern /example\.com$/ will reflect any request that is coming from an origin ending with "example.com".
    • Array - set origin to an array of valid origins. Each origin can be a String or a RegExp. For example ["http://example1.com", /\.example2\.com$/] will accept any request from "http://example1.com" or from a subdomain of "example2.com".
    • Function - set origin to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as callback(err, origin), where origin is a non-function value of the origin option) as the second.
  • methods: Configures the Access-Control-Allow-Methods CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: ['GET', 'PUT', 'POST']).

  • allowedHeaders: Configures the Access-Control-Allow-Headers CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: ['Content-Type', 'Authorization']). If not specified, defaults to reflecting the headers specified in the request's Access-Control-Request-Headers header.

  • exposedHeaders: Configures the Access-Control-Expose-Headers CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: ['Content-Range', 'X-Content-Range']). If not specified, no custom headers are exposed.

  • credentials: Configures the Access-Control-Allow-Credentials CORS header. Set to true to pass the header, otherwise it is omitted.

  • maxAge: Configures the Access-Control-Max-Age CORS header. Set to an integer to pass the header, otherwise it is omitted.

  • preflightContinue: Pass the CORS preflight response to the next handler.

  • optionsSuccessStatus: Provides a status code to use for successful OPTIONS requests, since some legacy browsers (IE11, various SmartTVs) choke on 204.

The default configuration is the equivalent of:

json
{
  "origin": "*",
  "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
  "allowedHeaders": "*",
  "exposedHeaders": "",
  "credentials": false,
  "maxAge": null,
  "preflightContinue": false,
  "optionsSuccessStatus": 204,
}

Released under the MIT License.