PHPackages                             hkvstore/cors-middleware - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. hkvstore/cors-middleware

ActiveLibrary[HTTP &amp; Networking](/categories/http)

hkvstore/cors-middleware
========================

PSR-7 and PSR-15 CORS middleware

v1.4.6(1y ago)07.6k↓38.9%MITPHPPHP ^8.1

Since Feb 2Pushed 1y agoCompare

[ Source](https://github.com/hkvstore/cors-middleware)[ Packagist](https://packagist.org/packages/hkvstore/cors-middleware)[ Docs](https://github.com/tuupola/cors-middleware)[ RSS](/packages/hkvstore-cors-middleware/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (13)Versions (4)Used By (0)

PSR-7 and PSR-15 CORS Middleware
================================

[](#psr-7-and-psr-15-cors-middleware)

This middleware implements [Cross-origin resource sharing](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing). It supports both PSR-7 style doublepass and PSR-15 middleware standards. It has been tested with [Slim Framework](http://www.slimframework.com/) and [Zend Expressive](https://zendframework.github.io/zend-expressive/). Internally the middleware uses [neomerx/cors-psr7](https://github.com/neomerx/cors-psr7) library for heavy lifting.

[![Latest Version](https://camo.githubusercontent.com/8b0d2eef00abeffb2456407f3a8b3fd8ad6f7b16b315a6867c98adfd6635e584/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f747575706f6c612f636f72732d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tuupola/cors-middleware)[![Packagist](https://camo.githubusercontent.com/c09708b387c553581ce92a94c51612dbefc6647b461237094364e38a3512e8cf/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f747575706f6c612f636f72732d6d6964646c65776172652e737667)](https://packagist.org/packages/tuupola/cors-middleware)[![Software License](https://camo.githubusercontent.com/55c0218c8f8009f06ad4ddae837ddd05301481fcf0dff8e0ed9dadda8780713e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![Build Status](https://camo.githubusercontent.com/27b0c5cd25ad659548eec11cbbc2a4f84d91368ec4286219ebcdc997c561e484/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f747575706f6c612f636f72732d6d6964646c65776172652f74657374732e796d6c3f6272616e63683d6d6173746572267374796c653d666c61742d737175617265)](https://github.com/tuupola/cors-middleware/actions)[![Coverage](https://camo.githubusercontent.com/0955b81de802cf5d5dd645b6d8c5de9eaaaf7d0308db42365dc5061881fd696a/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f747575706f6c612f636f72732d6d6964646c65776172652e7376673f7374796c653d666c61742d737175617265)](https://codecov.io/github/tuupola/cors-middleware)

Install
-------

[](#install)

Install using [composer](https://getcomposer.org/).

```
$ composer require tuupola/cors-middleware
```

Usage
-----

[](#usage)

Documentation assumes you have working knowledge of CORS. There are no mandatory parameters. If you are using Zend Expressive skeleton middlewares are added to file called `config/pipeline.php`. Note that you must disable the default `ImplicitOptionsMiddleware` for this middleware to work.

```
use Tuupola\Middleware\CorsMiddleware;

#$app->pipe(ImplicitOptionsMiddleware::class);
$app->pipe(CorsMiddleware::class);
```

Slim Framework does not have specified config files. Otherwise adding the middleware is similar with previous.

```
$app->add(new Tuupola\Middleware\CorsMiddleware);
```

Rest of the examples use Slim Framework.

If called without any parameters the following defaults are used.

```
$app->add(new Tuupola\Middleware\CorsMiddleware([
    "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->add(new Tuupola\Middleware\CorsMiddleware([
    "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
```

Parameters
----------

[](#parameters)

### Origin

[](#origin)

By default all origins are allowed. You can limit allowed origins by passing them as an array.

```
$app->add(new Tuupola\Middleware\CorsMiddleware([
    "origin" => ["app-1.example.com", "app-2.example.com"]
]));
```

You can also use wildcards to define multiple origins at once. Wildcards are matched by using the [fnmatch()](https://www.php.net/manual/en/function.fnmatch.php) function.

```
$app->add(new Tuupola\Middleware\CorsMiddleware([
    "origin" => ["*.example.com"]
]));
```

### Methods

[](#methods)

Methods can be passed either as an array or a callable which returns an array. Below example is for Zend Expressive where value of `methods` is dynamic depending on the requested route.

```
use Tuupola\Middleware\CorsMiddleware;
use Zend\Expressive\Router\RouteResult;

$app->pipe(new CorsMiddleware([
    "origin" => ["*"],
    "methods" => function($request) {
        $result = $request->getAttribute(RouteResult::class);
        $route = $result->getMatchedRoute();
        return $route->getAllowedMethods();
    }
]));
```

Same thing for Slim 3. This assumes you have **not** defined the `OPTIONS` route.

```
use Fastroute\Dispatcher;
use Tuupola\Middleware\CorsMiddleware;

$app->add(
    new CorsMiddleware([
        "origin" => ["*"],
        "methods" => function($request) use ($app) {
            $container = $app->getContainer();
            $dispatch = $container["router"]->dispatch($request);
            if (Dispatcher::METHOD_NOT_ALLOWED === $dispatch[0]) {
                return $dispatch[1];
            }
        }
    ])
);
```

### Logger

[](#logger)

The optional `logger` parameter allows you to pass in a PSR-3 compatible logger to help with debugging or other application logging needs.

```
$logger = Monolog\Logger("slim");
$rotating = new RotatingFileHandler(__DIR__ . "/logs/slim.log", 0, Logger::DEBUG);
$logger->pushHandler($rotating);

$app->add(new Tuupola\Middleware\CorsMiddleware([
    "logger" => $logger,
]));
```

### Error

[](#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->add(new Tuupola\Middleware\CorsMiddleware([
    "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."
}

```

### Server origin

[](#server-origin)

If your same-origin requests contain an unnecessary `Origin` header, they might get blocked in case the server origin is not among the allowed origins already. In this case you can use the optional `origin.server` parameter to specify the origin of the server.

```
$app->add(new Tuupola\Middleware\CorsMiddleware([
    "origin.server" => "https://example.com"
]));
```

```
$ curl https://example.com/api \
    --request POST \
    --include \
    --header "Origin: https://example.com"

HTTP/1.1 200 OK

```

Testing
-------

[](#testing)

You can run tests either manually or automatically on every code change. Automatic tests require [entr](http://entrproject.org/) to work.

```
$ make test
```

```
$ brew install entr
$ make watch
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

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

License
-------

[](#license)

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

###  Health Score

34

—

LowBetter than 77% of packages

Maintenance42

Moderate activity, may be stable

Popularity23

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 90.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

470d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6fc3d3f9a4c5f6cba9ff19b64c2e628147bd91a391b81021d94c0908754330af?d=identicon)[hkvstore](/maintainers/hkvstore)

---

Top Contributors

[![tuupola](https://avatars.githubusercontent.com/u/21913?v=4)](https://github.com/tuupola "tuupola (127 commits)")[![hkvstore](https://avatars.githubusercontent.com/u/16445695?v=4)](https://github.com/hkvstore "hkvstore (3 commits)")[![jankonas](https://avatars.githubusercontent.com/u/7345659?v=4)](https://github.com/jankonas "jankonas (3 commits)")[![usox](https://avatars.githubusercontent.com/u/5184763?v=4)](https://github.com/usox "usox (3 commits)")[![mikhailidi](https://avatars.githubusercontent.com/u/12273645?v=4)](https://github.com/mikhailidi "mikhailidi (2 commits)")[![Pnoexz](https://avatars.githubusercontent.com/u/3297901?v=4)](https://github.com/Pnoexz "Pnoexz (1 commits)")[![fabacino](https://avatars.githubusercontent.com/u/14901115?v=4)](https://github.com/fabacino "fabacino (1 commits)")

---

Tags

psr-7middlewarecorspsr-15

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StyleECS

Type Coverage Yes

### Embed Badge

![Health badge](/badges/hkvstore-cors-middleware/health.svg)

```
[![Health](https://phpackages.com/badges/hkvstore-cors-middleware/health.svg)](https://phpackages.com/packages/hkvstore-cors-middleware)
```

###  Alternatives

[tuupola/cors-middleware

PSR-7 and PSR-15 CORS middleware

1331.8M24](/packages/tuupola-cors-middleware)[tuupola/slim-basic-auth

PSR-7 and PSR-15 HTTP Basic Authentication Middleware

4442.0M26](/packages/tuupola-slim-basic-auth)[mezzio/mezzio

PSR-15 Middleware Microframework

3883.6M97](/packages/mezzio-mezzio)[relay/relay

A PSR-15 server request handler.

3302.1M86](/packages/relay-relay)[hkarlstrom/openapi-validation-middleware

PSR-7 and PSR-15 OpenAPI Validation Middleware

95198.8k1](/packages/hkarlstrom-openapi-validation-middleware)[laminas/laminas-stratigility

PSR-7 middleware foundation for building and dispatching middleware pipelines

586.6M81](/packages/laminas-laminas-stratigility)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
