0xlaradev's avatar

Error CORS policy no 'Access-Control-Allow-Origin' with Laravel 11

Hi! I'm getting this error: "Access to XMLHttpRequest at 'https://www.domain1.com/path1' from origin 'https://www.domain2.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."

After researching it, it looks that I need to add a CORS policy in domain1.com that allows domain2.com to access the resources.

The issue is that all the documentation that I have found is from older versions than Laravel 11. And since Laravel 11 doesn't have the kernel.php file, I got stuck.

Here's what I have done.

First I ran "php artisan make:middleware Cors". This created the Cors.php file in app/Http/Middleware. Then I added "return $next($request)->header('Access-Control-Allow-Origin', '*');" inside the public function, like this:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request)->header('Access-Control-Allow-Origin', '*');
    }
}

Firstly, I don't know if that is right. And also, after that I think there's something else I have to add in bootstrap/app.php instead of kernel.php since it was changed in Laravel 11 but I can't seem to find out how it should go.

This is what I currently have in bootstrap/app.php:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->validateCsrfTokens(except: [
            env('APP_URL') . '/researchjspost'
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

Can someone tell me if this is the correct path, if Cors.php is correct, what should I add in bootstrap/app.php and what else am I missing? Thanks!

1 like
11 replies
LaryAI's avatar
Level 58

The solution you've started with by creating a Cors middleware is a good approach. However, you need to ensure that the middleware is registered and executed with every HTTP request that requires CORS headers.

Here's how you can adjust your Cors middleware and register it in Laravel 11:

  1. Update your Cors middleware to include all necessary CORS headers:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return \Illuminate\Http\Response
     */
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);

        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
        $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, X-Auth-Token, Origin, Authorization');

        return $response;
    }
}
  1. Register your Cors middleware in bootstrap/app.php. You can do this by adding it to the global middleware stack or as a route middleware. Here's how you can add it to the global middleware stack:
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use App\Http\Middleware\Cors; // Import your Cors middleware

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->validateCsrfTokens(except: [
            env('APP_URL') . '/researchjspost'
        ]);
        $middleware->pushMiddleware(Cors::class); // Register Cors middleware
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

By adding the Cors middleware to the global middleware stack, it will be applied to all routes in your application. If you want to apply it only to specific routes, you can instead add it as a route middleware and then use it in your routes or route groups.

Remember to replace the wildcard * in the Access-Control-Allow-Origin header with the specific domain you want to allow if you don't want to allow all origins.

After making these changes, your Laravel 11 application should correctly handle CORS and include the necessary headers in the HTTP response.

2 likes
0xlaradev's avatar

Amazing, Lary's answer pointed me in the right direction BUT, just as it it, it was giving a fatal 500 error with no debugging information.

Here's what I changed.

Changed Cors.php function to Larry's proposal like this:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next)
    {
        $response = $next($request);
        $response->headers->set('Access-Control-Allow-Origin', '*');
        $response->headers->set('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
        $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, X-Auth-Token, Origin, Authorization');

        return $response;
    }
}

The error that was generated though, was by using pushMiddleware in bootstrap/app.php as Lary suggested. So I changed it to "append", following Laravel's 11 documentation. The final bootstrap/app.php file now looks like:

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use App\Http\Middleware\Cors;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->validateCsrfTokens(except: [
            env('APP_URL') . '/researchjspost'
        ]);
        $middleware->append(Cors::class);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

I tried it and it worked! Please let me know if there's something else I should be looking at. Thanks.

1 like
Kenta3's avatar

@dlom do you have an example for your solution? Looks like you fixed the problem only with the cors file. I look at the link you put here. My file looks like

<?php

return [

'paths' => ['my/web/page'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*.example.org'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,

];

Did i miss something or have you another idea what i do wrong?

0xlaradev's avatar

@Kenta3 yes, this is how my cors.php file looks:


return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*', 'sanctum/csrf-cookie', 'researchjspost'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => false,

];

What I'm seeing different from your code is the 'allowed_origins' piece. I only have *, while on yours there is '*.example.org'. Also look at 'paths', the last element is the path that I was trying to access in routes/web.php:

<?php

use App\Models\User;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProjectController;

// Home
Route::get('/', [ProjectController::class, 'index']);

// Account management
Route::get('/register', [ProjectController::class, 'register']);

// Processing submissions
Route::get('/researchjs.js', [ProjectController::class, 'researchjs']);
Route::post('/researchjspost', [ProjectController::class, 'researchjspost']);

// // Get server information
// Route::get('phpmyinfo', function () {phpinfo();})->name('phpmyinfo');

// Visualize results
Route::get('results', [ProjectController::class, 'results']);

Kenta3's avatar

@dlom thanks for the help but didn't work for me. I want to make a option with a steam login with socialite but get everytime the problem with the cors error. It's the same like you with "Access to XMLHttpRequest at 'https:// domain1.com/path1' (redirected from 'http:// domain2:8086/auth/steam') from origin 'http:// domain2:8086' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."

So looks like the route of my routes/web.php

<?php

use App\Http\Controllers\Auth\SteamController;
use Illuminate\Support\Facades\Route;

Route::get('/auth/steam', [SteamController::class,'redirect']);
Route::get('/auth/steam/callback', SteamController::class,'handleCallback');

And the cors.php so

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https:// developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*', 'sanctum/csrf-cookie','auth/steam'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => false,

];

so I'm currently a bit confused as to what the problem might be. Looks like i should open a new thread

Kenta3's avatar

@chithract hey, sry for the late response, the last days i didn't work on this project. I ask at this thread for a solution https:// laracasts.com/discuss/channels/laravel/cors-error-in-laravel-11 . In my case it helps to change the vue link-tag to an a-tag. You must remove the space between https.// and laracast. I can't put links here

1 like
fenox's avatar
fenox
Best Answer
Level 1

first run

php artisan config:publish cors

then modify the config/cors.php file

	'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true, // by default is false -> change to true

ready :D

4 likes

Please or to participate in this conversation.