Skip to content
This repository has been archived by the owner on Jun 11, 2021. It is now read-only.

Commit

Permalink
prepare for release
Browse files Browse the repository at this point in the history
  • Loading branch information
freekmurze committed Mar 9, 2018
2 parents eafbd34 + 300d359 commit 7e5fa8d
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 36 deletions.
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to `laravel-cors` will be documented in this file

## 1.0.0 - 201X-XX-XX
## 1.0.4 - 2018-03-09

- allow to customize error message

## 1.0.3 - 2018-02-28

- fix typo in config

## 1.0.2 - 2018-02-12

- add support for Lumen

## 1.0.1 - 2018-02-07

- add support for Laravel 5.6

## 1.0.0 - 2018-12-19

- initial release
82 changes: 62 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,48 @@

[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-cors.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-cors)
[![Build Status](https://img.shields.io/travis/spatie/laravel-cors/master.svg?style=flat-square)](https://travis-ci.org/spatie/laravel-cors)
[![SensioLabsInsight](https://img.shields.io/sensiolabs/i/e913c9eb-556b-4e2e-84b8-3913ed46a87a.svg?style=flat-square)](https://insight.sensiolabs.com/projects/e913c9eb-556b-4e2e-84b8-3913ed46a87a)
[![Quality Score](https://img.shields.io/scrutinizer/g/spatie/laravel-cors.svg?style=flat-square)](https://scrutinizer-ci.com/g/spatie/laravel-cors)
[![StyleCI](https://styleci.io/repos/113957368/shield?branch=master)](https://styleci.io/repos/113957368)
[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-cors.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-cors)

This package will add CORS headers to the reponses of your Laravel. Read [this excellent article](https://spring.io/understanding/CORS) on the subject if you want to understand what CORS is all about.
This package will add CORS headers to the responses of your Laravel or Lumen app. Read [this excellent article](https://spring.io/understanding/CORS) on the subject if you want to understand what CORS is all about.

This package support preflight request and is easily configurable to fit your needs.
This package supports preflight requests and is easily configurable to fit your needs.

## Installation

You can install the package via composer:
- [Laravel](#laravel)
- [Lumen](#lumen)

### Laravel

You can install the package via Composer:

```bash
composer require spatie/laravel-cors
```

The package will automatically register it's service provider.
The package will automatically register its service provider.

The provided `Spatie\Cors\Cors` middleware must be registered in the global middleware group.

Or you could opt to register it as global middleware.

```php
// app/Http/Kernel.php

protected $middleware = [
...
Spatie\Cors\Cors::class
\Spatie\Cors\Cors::class
];
```

```php
php artisan vendor:publish --provider="Spatie\Cors\CorsServiceProvider" --tag="cors"
php artisan vendor:publish --provider="Spatie\Cors\CorsServiceProvider" --tag="config"
```

This is the default content of the config file published at `config/cors.php`:

```php
return [

/*
* A cors profile determines which orgins, methods, headers are allowed for
* a given requests. The `DefaultProfile` reads its configuration from this
Expand All @@ -54,20 +55,21 @@ return [
'cors_profile' => Spatie\Cors\CorsProfile\DefaultProfile::class,

/*
* These configuration is used by `DefaultProfile`.
* This configuration is used by `DefaultProfile`.
*/
'default_profile' => [

'allow_origins' => [
'*'
'*',
],

'allow_methods' => [
'POST',
'GET',
'OPTIONS',
'PUT',
'DELETE'
'PATCH',
'DELETE',
],

'allow_headers' => [
Expand All @@ -76,6 +78,11 @@ return [
'Origin',
'Authorization',
],

'forbidden_response' => [
'message' => 'Forbidden (cors).',
'status' => 403,
],

/*
* Preflight request will respond with value for the max age header.
Expand All @@ -85,11 +92,37 @@ return [
];
```

### Lumen

You can install the package via Composer:

```bash
composer require spatie/laravel-cors
```

Copy the config file from the vendor directory:

```bash
cp vendor/spatie/laravel-cors/config/cors.php config/cors.php
```

Register the config file, the middleware and the service provider in `bootstrap/app.php`:

```php
$app->configure('cors');

$app->middleware([
Spatie\Cors\Cors::class,
]);

$app->register(Spatie\Cors\CorsServiceProvider::class);
```

## Usage

With the middleware installed your api routes should now get apprioriate cors headers. Preflight requests will be handled as well. If a request comes in that is not allowed, Laravel will return a `403` response.
With the middleware installed your API routes should now get apprioriate CORS headers. Preflight requests will be handled as well. If a request comes in that is not allowed, Laravel will return a `403` response.

The default configuration of this package allows all requests from any origin. You probably want to at least specify some origins. If you want to allow requests to come in in from `https://spatie.be` and `https://laravel.com` add those domains to the config file:
The default configuration of this package allows all requests from any origin (denoted as `'*'`). You probably want to at least specify some origins relevant to your project. If you want to allow requests to come in from `https://spatie.be` and `https://laravel.com` add those domains to the config file:

```php
// config/cors.php
Expand All @@ -105,16 +138,16 @@ The default configuration of this package allows all requests from any origin. Y
...
```

### Creating your own cors profile
### Creating your own CORS profile

Imagine you want to specify allowed origins based on the user that is currently logged in. In that case the `DefaultProfile` which just reads the config file won't cut it. Fortunately it's very easy to write your own cors profile. A valid cors profile is any class that extends `Spatie\Cors\DefaultProfile`.
Imagine you want to specify allowed origins based on the user that is currently logged in. In that case the `DefaultProfile` which just reads the config file won't cut it. Fortunately it's very easy to write your own CORS profile, which is simply a class that extends `Spatie\Cors\DefaultProfile`.

Here's a quick example where it is assumed that you've already added a `allowed_domains` column on your user model:
Here's a quick example where it is assumed that you've already added an `allowed_domains` column on your user model:

```php
namespace App\Services\Cors;

use Spatie\Cors\DefaultProfile;
use Spatie\Cors\CorsProfile\DefaultProfile;

class UserBasedCorsProfile extends DefaultProfile;
{
Expand All @@ -125,6 +158,15 @@ class UserBasedCorsProfile extends DefaultProfile;
}
```

You can override the default HTTP status code and message returned when a request is forbidden by editing the `forbidden_response` array in your configuration file:

```php
'forbidden_response' => [
'message' => 'Your request failed',
'status' => 400,
],
```

Don't forget to register your profile in the config file.

```php
Expand Down Expand Up @@ -157,7 +199,7 @@ If you discover any security related issues, please email freek@spatie.be instea

## Alternatives

- [barryvdh/laravel-cors](barryvdh/laravel-cors): a tried and tested package. Our package is a modern rewrite of the basic features of Barry's excellent one. We created our own solution because we needed our configuration to be [very flexible](/#creating-your-own-cors-profile).
- [barryvdh/laravel-cors](https://github.com/barryvdh/laravel-cors): a tried and tested package. Our package is a modern rewrite of the basic features of Barry's excellent one. We created our own solution because we needed our configuration to be [very flexible](#creating-your-own-cors-profile).

## Postcardware

Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "spatie/laravel-cors",
"description": "Send CORS headers in a Laravel application",
"description": "Send CORS headers in a Laravel or Lumen application",
"keywords": [
"spatie",
"laravel-cors",
Expand All @@ -21,11 +21,11 @@
],
"require": {
"php": "^7.0",
"illuminate/support": "5.5.*",
"orchestra/testbench": "3.5.0"
"illuminate/support": "5.5.*|5.6.*"
},
"require-dev": {
"phpunit/phpunit": "^6.5.4"
"orchestra/testbench": "3.5.*|3.6.*",
"phpunit/phpunit": "^6.5.4|^7.0"
},
"autoload": {
"psr-4": {
Expand Down
10 changes: 8 additions & 2 deletions config/cors.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
return [

/*
* A cors profile determines which orgins, methods, headers are allowed for
* A cors profile determines which origins, methods, headers are allowed for
* a given requests. The `DefaultProfile` reads its configuration from this
* config file.
*
Expand All @@ -13,7 +13,7 @@
'cors_profile' => Spatie\Cors\CorsProfile\DefaultProfile::class,

/*
* These configuration is used by `DefaultProfile`.
* This configuration is used by `DefaultProfile`.
*/
'default_profile' => [

Expand All @@ -26,6 +26,7 @@
'GET',
'OPTIONS',
'PUT',
'PATCH',
'DELETE',
],

Expand All @@ -36,6 +37,11 @@
'Authorization',
],

'forbidden_response' => [
'message' => 'Forbidden (cors).',
'status' => 403,
],

/*
* Preflight request will respond with value for the max age header.
*/
Expand Down
23 changes: 21 additions & 2 deletions src/Cors.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public function __construct(CorsProfile $corsProfile)
*/
public function handle($request, Closure $next)
{
if (! $this->isCorsRequest($request)) {
return $next($request);
}

$this->corsProfile->setRequest($request);

if (! $this->corsProfile->isAllowed()) {
Expand All @@ -40,6 +44,15 @@ public function handle($request, Closure $next)
return $this->corsProfile->addCorsHeaders($response);
}

protected function isCorsRequest($request): bool
{
if (! $request->headers->has('Origin')) {
return false;
}

return $request->headers->get('Origin') !== $request->getSchemeAndHttpHost();
}

protected function isPreflightRequest($request): bool
{
return $request->getMethod() === 'OPTIONS';
Expand All @@ -51,11 +64,17 @@ protected function handlePreflightRequest()
return $this->forbiddenResponse();
}

return $this->corsProfile->addPreflightheaders(response('Preflight OK', 200));
return $this->corsProfile->addPreflightHeaders(response('Preflight OK', 200));
}

protected function forbiddenResponse()
{
return response('Forbidden.', 403);
$message = config('cors.default_profile.forbidden_response.message');
$status = config('cors.default_profile.forbidden_response.status');

return response(
$message ?? 'Forbidden (cors).',
$status ?? 403
);
}
}
4 changes: 4 additions & 0 deletions src/CorsProfile/CorsProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public function allowMethods(): array;

public function allowHeaders(): array;

public function addCorsHeaders($response);

public function addPreflightHeaders($response);

public function maxAge(): int;

public function isAllowed(): bool;
Expand Down
17 changes: 15 additions & 2 deletions src/CorsProfile/DefaultProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ public function maxAge(): int
public function addCorsHeaders($response)
{
return $response
->header('Access-Control-Allow-Origin', $this->toString($this->allowOrigins()));
->header('Access-Control-Allow-Origin', $this->allowedOriginsToString());
}

public function addPreflightHeaders($response)
{
return $response
->header('Access-Control-Allow-Methods', $this->toString($this->allowMethods()))
->header('Access-Control-Allow-Headers', $this->toString($this->allowHeaders()))
->header('Access-Control-Allow-Origin', $this->toString($this->allowOrigins()))
->header('Access-Control-Allow-Origin', $this->allowedOriginsToString())
->header('Access-Control-Max-Age', $this->maxAge());
}

Expand All @@ -64,4 +64,17 @@ protected function toString(array $array): string
{
return implode(', ', $array);
}

protected function allowedOriginsToString(): string
{
if (! $this->isAllowed()) {
return '';
}

if (in_array('*', $this->allowOrigins())) {
return '*';
}

return $this->request->header('Origin');
}
}
11 changes: 9 additions & 2 deletions src/CorsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CorsServiceProvider extends ServiceProvider
{
public function boot()
{
if ($this->app->runningInConsole()) {
if ($this->isLaravel() && $this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/../config/cors.php' => config_path('cors.php'),
], 'config');
Expand All @@ -28,6 +28,13 @@ public function boot()

public function register()
{
$this->mergeConfigFrom(__DIR__.'/../config/cors.php', 'cors');
if ($this->isLaravel()) {
$this->mergeConfigFrom(__DIR__.'/../config/cors.php', 'cors');
}
}

protected function isLaravel()
{
return ! preg_match('/lumen/i', app()->version());
}
}
Loading

0 comments on commit 7e5fa8d

Please sign in to comment.