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.
leaf install cors
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.
app()->cors();
// ... your app
$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.
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://
.
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:
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:
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
- setorigin
to a specific origin. For example if you set it to"http://example.com"
only requests from "http://example.com" will be allowed.RegExp
- setorigin
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
- setorigin
to an array of valid origins. Each origin can be aString
or aRegExp
. For example["http://example1.com", /\.example2\.com$/]
will accept any request from "http://example1.com" or from a subdomain of "example2.com".Function
- setorigin
to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called ascallback(err, origin)
, whereorigin
is a non-function value of theorigin
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 totrue
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 successfulOPTIONS
requests, since some legacy browsers (IE11, various SmartTVs) choke on204
.
The default configuration is the equivalent of:
{
"origin": "*",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"allowedHeaders": "*",
"exposedHeaders": "",
"credentials": false,
"maxAge": null,
"preflightContinue": false,
"optionsSuccessStatus": 204,
}