bairwell / middleware-cors
A PSR-7 middleware layer for providing CORS (Cross Origin Request Security) headers and security provisions. Instead of just allowing invalid CORs requests to come through, this middleware actively blocks them after validating.
Installs: 17 014
Dependents: 1
Suggesters: 0
Security: 0
Stars: 18
Watchers: 2
Forks: 7
Open Issues: 4
Requires
- php: ^7.0
- psr/http-message: ^1.0
- psr/log: ~1.0
Requires (Dev)
- monolog/monolog: ^1.13
- phpunit/phpunit: ^5.1
- squizlabs/php_codesniffer: ^2.5
This package is auto-updated.
Last update: 2024-11-29 04:41:28 UTC
README
This is a PHP 7 Composer compatible library for providing a 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 // add CORs $slim->add(new MiddlewareCors()); // 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 by:
$slim = new \Slim\App(); // use Slim3 as it supports PSR7 middleware $config = [ 'origin' => '*.example.com' // allow all hosts ending example.com ]; // add CORs $slim->add(new MiddlewareCors($config)); // 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:
- PSR 1 - Basic Coding Standard
- PSR 2 - Coding Style Guide
- PSR 3 - Logger Interface
- PSR 4 - Autoloading Standard
- PSR 5 - PHPDoc Standard - (still in draft)
- PSR 7 - HTTP Message Interface
- PSR 12 - Extended Coding Style Guide - (still in draft)
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:
- "Sponsorship" via a monthly donation via Patreon
- Reporting issues
- Making updates via Github
- Spreading the word.
- Just letting me know what you think of it via Twitter or via Bairwell Ltd