DEV Community

Cover image for Handling CORS with Laravel
Kenta Takeuchi
Kenta Takeuchi

Posted on • Originally published at bmf-tech.com

Handling CORS with Laravel

This article was originally published on bmf-tech.com.

Overview

This post summarizes how to handle CORS (Cross-Origin Resource Sharing) in Laravel. The client-side uses React and axios. As a prerequisite, it's good to understand the types of CORS requests, the difference between simple request methods, and requests using preflight. For RESTful APIs, requests typically use preflight. This article covers examples of handling requests using preflight.

Environment

Since it's CORS, it's obvious that we have separate domains for the API and web.

The setup involves domains like api.hogehogedomain and admin.hogehogedomain, where the admin calls an API managed on a different domain.

Prepare Middleware

On the Laravel side, which provides the API, we prepare middleware to adjust header information during API requests.

Initially, I wanted to create custom middleware, but for some reason, it didn't work well with update methods, so I decided to use barryvdh/laravel-cors.

Setup follows the README instructions.

composer require barryvdh/laravel-cors

Specify the following in the provider array of config/app.php
Barryvdh\Cors\ServiceProvider::class,

Set the cors middleware in the api middleware group of app/Http/Kernel.php

    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            'throttle:60,1',
            'bindings',
            \Barryvdh\Cors\HandleCors::class, // <-Here!
        ],
    ];
Enter fullscreen mode Exit fullscreen mode

Publish and edit the configuration file.
php artisan vendor:publish --provider="Barryvdh\Cors\ServiceProvider"

config/cors.php

return [
     /*
     |--------------------------------------------------------------------------
     | Laravel CORS
     |--------------------------------------------------------------------------
     |
     | allowedOrigins, allowedHeaders and allowedMethods can be set to array('*')
     | to accept any value.
     |
     */
    'supportsCredentials' => true, // change false to true !
    'allowedOrigins' => ['*'],
    'allowedHeaders' => ['Content-Type', 'X-Requested-With'],
    'allowedMethods' => ['*'], // ex: ['GET', 'POST', 'PUT',  'DELETE']
    'exposedHeaders' => [],
    'maxAge' => 0,
]
Enter fullscreen mode Exit fullscreen mode

Since we want to allow cookie transmission and Basic authentication, set supportsCredentials to true.

That's all for the server-side settings.

Calling the API from the Client Side

Define header information with axios.

action/index.js

const api = axios.create({
  baseURL: 'http://api.rubel/v1',
  timeout: 10000,
  headers: {
    'X-Requested-With': 'XMLHttpRequest'
  }
});

export function createCategory(props) {
  const request = api.post(`/categories`, props);

  return {type: CREATE_CATEGORY, payload: request};
}
Enter fullscreen mode Exit fullscreen mode

On the client side, just set the X-Requested-With header, and then you can normally call the API.

Thoughts

I haven't resolved why the custom middleware didn't work well, which is unsatisfactory, but for now, this should be fine.

References

Top comments (0)