Skip to content

PSR-7 compatible middleware to provide CORs facilities.

License

Notifications You must be signed in to change notification settings

B3none/middleware-cors

 
 

Repository files navigation

Bairwell\Middleware-Cors

Latest Stable Version License SensioLabsInsight Coverage Status Build Status Total Downloads

This is a PHP 7 Composer compatible library for providing a [PSR-7]((http://www.php-fig.org/psr/psr-7/) compatible middleware layer for handling "CORS" (Cross Origin Request Security/Cross-Origin Http Request/HTTP access control) headers and security.

What does this library provides over other CORs libraries?

  • PHP-7 type declarations.
  • Works as a piece of PSR-7 middleware making it compatible with many frameworks (such as Slim 3 and Symfony)
  • Massively flexibility over configuration settings (most can be strings, arrays or callbacks).
  • Follows the CORs flowchart and actively rejects invalid requests.
  • Only sends the appropriate headers when necessary.
  • On CORs "OPTIONS" request, ensure a blank page 204 "No Content" page is returned instead of returning unwanted content bodies.
  • Supports PSR-3 based loggers for debugging purposes.
  • Ignores non-CORs "OPTIONS" requests (for example, on REST services). A CORs request is indicated by the presence of the Origin: header on the inbound request.
  • Fully unit tested.
  • Licensed under the MIT License allowing you to practically do whatever you want.
  • Uses namespaces and is 100% object orientated.
  • Blocks invalid settings.
  • Minimal third party requirements (just the definition files "psr/http-message" and "psr/log" as interface definitions, and PHPUnit, PHPCodeSniffer, and Monolog for development/testing).

Installation

Install the latest version with Composer via:

$ composer require bairwell/middleware-cors

or by modifying your composer.json file:

{
    "require": {
        "bairwell/middleware-cors" : "@stable"
    }
}

or from the Github repository (which is needed to be able to fork and contribute):

$ git clone git://github.com:bairwell/middleware-cors.git

Usage

You can utilise this CORs library as simply as:

$slim=new \Slim\App(); // use Slim3 as it supports PSR7 middleware
$slim->add(new MiddlewareCors()); // add CORs
// add routes
$slim->run(); // get Slim running

but that won't really add much (as it allows all hosts origin and methods by default).

You can make it slightly more complex such as:

$slim=new \Slim\App(); // use Slim3 as it supports PSR7 middleware
$config=[
    'origin'=>'*.example.com' // allow all hosts ending example.com
];
$slim->add(new MiddlewareCors($config)); // add CORs
// add routes
$slim->run(); // get Slim running

or

$slim=new \Slim\App(); // use Slim3 as it supports PSR7 middleware
$config=[
    'origin'=>['*.example.com','*.example.com.test','example.com','dev.*',
    'allowCredentials'=>true
];
$slim->add(new MiddlewareCors($config)); // add CORs
// add routes
$slim->run(); // get Slim running

which will allow all Origins ending .example.com or *.example.com.test, the exact example.com origin or any host starting with dev. It'll also allow credentials to be allowed.

For a more complicated integration which relies on the Slim router to feed back which methods are actually allowed per route, see tests/MiddlewareCors/FunctionalTests/SlimTest.php

Suggested settings

// read the allowed methods for a route
 $corsAllowedMethods = function (ServerRequestInterface $request) use ($container) : array {

            // if this closure is called, make sure it has the route available in the container.
            /* @var RouterInterface $router */
            $router = $container->get('router');

            $routeInfo = $router->dispatch($request);
            $methods   = [];
            // was the method called allowed?
            if ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
                $methods = $routeInfo[1];
            } else {
                // if it was, see if we can get the routes and then the methods from it.
                // @var \Slim\Route $route
                $route = $request->getAttribute('route');
                // has the request get a route defined? is so use that
                if (null !== $route) {
                    $methods = $route->getMethods();
                }
            }

            // if we have methods, let's list them removing the OPTIONs one.
            if (0 === count($methods)) {
                // find the OPTIONs method
                $key = array_search('OPTIONS', $methods,true);
                // and remove it if set.
                if (false !== $key) {
                    unset($methods[$key]);
                    $methods = array_values($methods);
                }
            }

            return $methods;
        };
$cors = new MiddlewareCors(
                [
                    'origin'           => ['*.example.com','example.com','*.example.com.test','192.168.*','10.*'],
                    'exposeHeaders'    => '',
                    'maxAge'           => 120,
                    'allowCredentials' => true,
                    'allowMethods'     => $corsAllowedMethods,
                    'allowHeaders'     => ['Accept', 'Accept-Language', 'Authorization', 'Content-Type','DNT','Keep-Alive','User-Agent','X-Requested-With','If-Modified-Since','Cache-Control','Origin'],
                ]
            );
$slim->add($cors);

Standards

The following PHP FIG standards should be followed:

Standards Checking

PHP Code Sniffer highlights potential coding standards issues.

vendor/bin/phpcs

PHP CS will use the configuration in phpcs.xml.dist by default.

To see which sniffs are running add "-s"

Unit Tests

PHPUnit is installed for unit testing (tests are in tests)

To run unit tests: vendor/bin/phpunit

For a list of the tests that have ran: vendor/bin/phpunit --tap

To restrict the tests run: vendor/bin/phpunit --filter 'MiddlewareCors\\Exceptions\\BadOrigin'

or just

vendor/bin/phpunit --filter 'ExceptionTest'

for all tests which have "Exception" in them and: vendor/bin/phpunit --filter '(ExceptionTest::testEverything|ExceptionTest::testStub)'

to test the two testEverything and testStub methods in the ExceptionTest class (for example).

Licence/License

Licenced under the MIT license. See LICENSE.md for full information.

Bairwell/MiddlewareCors is Copyright (c) Bairwell Ltd/Richard Bairwell 2016.

Supporting development

You can help support development of this library via a variety of methods:

About

PSR-7 compatible middleware to provide CORs facilities.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%