tuupola/cors-middleware

0.5.2 2016-08-12 13:12 UTC

README

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.

Latest Version Software License Build Status Coverage

Install

Install using composer.

$ composer require tuupola/cors-middleware

Usage

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

Other parameters

Logger

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

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."
}

Testing

You can run tests either manually...

$ make test

... or automatically on every code change.

$ brew install entr
$ make watch

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security related issues, please email tuupola@appelsiini.net instead of using the issue tracker.

License

The MIT License (MIT). Please see License File for more information.