This middleware implements Cross-origin resource sharing. It was originally developed for Slim but can be used with all frameworks using PSR-7 style middlewares. It has been tested with Slim Framework and Zend Expressive. Internally the middleware uses neomerx/cors-psr7 library for heavy lifting.
Install using composer.
$ composer require tuupola/cors-middleware
Documentation assumes you have working knowledge of CORS. There are no mandatory parameters. If called without any parameters the following defaults are used. Examples assume you are using Slim Framework.
$app = new \Slim\App();
$app->add(new \Tuupola\Middleware\Cors([
"origin" => ["*"],
"methods" => ["GET", "POST", "PUT", "PATCH", "DELETE"],
"headers.allow" => [],
"headers.expose" => [],
"credentials" => false,
"cache" => 0,
]));
$ curl "https://api.example.com/" \
--request OPTIONS \
--include
--header "Access-Control-Request-Method: PUT" \
--header "Origin: http://www.example.com"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.example.com
Vary: Origin
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
However, you most likely want to change some of the defaults. For example if developing a REST API which supports caching and conditional requests you could use the following.
$app = new \Slim\App();
$app->add(new \Tuupola\Middleware\Cors([
"origin" => ["*"],
"methods" => ["GET", "POST", "PUT", "PATCH", "DELETE"],
"headers.allow" => ["Authorization", "If-Match", "If-Unmodified-Since"],
"headers.expose" => ["Etag"],
"credentials" => true,
"cache" => 86400
]));
$ curl "https://api.example.com/foo" \
--request OPTIONS \
--include \
--header "Origin: http://www.example.com" \
--header "Access-Control-Request-Method: PUT" \
--header "Access-Control-Request-Headers: Authorization, If-Match"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.example.com
Access-Control-Allow-Credentials: true
Vary: Origin
Access-Control-Max-Age: 86400
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: authorization, if-match, if-unmodified-since
$ curl "https://api.example.com/foo" \
--request PUT \
--include \
--header "Origin: http://www.example.com"
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://www.example.com
Access-Control-Allow-Credentials: true
Vary: Origin
Access-Control-Expose-Headers: Etag
The optional logger
parameter allows you to pass in a PSR-3 compatible logger to help with debugging or other application logging needs.
$app = new \Slim\App();
$logger = \Monolog\Logger("slim");
$rotating = new RotatingFileHandler(__DIR__ . "/logs/slim.log", 0, Logger::DEBUG);
$logger->pushHandler($rotating);
$app->add(new \Tuupola\Middleware\Cors([
"logger" => $logger,
]));
Error is called when CORS request fails. It receives last error message in arguments. This can be used for example to create application/json
responses when CORS request fails.
$app = new \Slim\App();
$app->add(new \Tuupola\Middleware\Cors([
"methods" => ["GET", "POST", "PUT"],
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
]));
$ curl https://api.example.com/foo \
--request OPTIONS \
--include \
--header "Access-Control-Request-Method: PATCH" \
--header "Origin: http://www.example.com"
HTTP/1.1 401 Unauthorized
Content-Type: application/json
Content-Length: 83
{
"status": "error",
"message": "CORS requested method is not supported."
}
You can run tests either manually...
$ vendor/bin/phpunit
$ vendor/bin/phpcs --standard=PSR2 src/ -p
... or automatically on every code change.
$ npm install
$ grunt watch
Please see CONTRIBUTING for details.
If you discover any security related issues, please email tuupola@appelsiini.net instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.