In this laravel tutorial titled “Laravel 12 CORS Middleware Configuration Example”, you will learn how to configure CORS Middleware in laravel 12 application step by step.
When building APIs or frontend–backend integrated applications, you often need to allow cross-origin requests. This is where CORS (Cross-Origin Resource Sharing) comes in. In Laravel 12, configuring CORS is simple and efficient using built-in middleware.
In this laravel 12 tutorial, we’ll walk through how to set up and configure CORS in Laravel 12, customize allowed origins, methods, headers, and how to apply CORS middleware globally or to specific routes.
Table of Contents
What is CORS ?
CORS (Cross-Origin Resource Sharing) is a security mechanism implemented by browsers to allow or block requests coming from different domains.
An “origin” means the protocol (http/https), domain, and port number.
Example of different origins:
- http://localhost:8000 Laravel backend
- http://localhost:5173 Vue/React frontend
- https://api.example.com and https://example.com different origins
Normally, browsers block requests between different origins to keep users safe.
CORS allows the server to say: “Yes, this other website is allowed to access my data.”
When You Need CORS
You need CORS when:
- Your frontend (React, Vue, Angular) runs on a different port/domain than your Laravel API
- You have multiple services (microservices) talking to each other
- A mobile app calls your Laravel API
- You want third-party apps or developers to use your API
Read Also : Laravel 12 RouteServiceProvider Configuration Tutorial
How CORS Works in Laravel
When a browser sends a request to another origin, it works in two ways:
Simple Requests
- Basic GET, POST, or HEAD requests.
- The browser sends the request with an Origin header, and Laravel replies with the correct CORS headers.
Preflight Requests
- Used for complex requests (PUT, DELETE, custom headers, JSON, etc.).
- Before sending the real request, the browser sends an OPTIONS request to ask the server for permission.
- This is called a preflight request.
Laravel handles both types automatically using the HandleCors middleware.
Laravel 12 Built-in CORS Support
Laravel 12 comes with built-in CORS support—no extra packages are needed. The HandleCors middleware is already included and active in every project.
Step 1: Publish the CORS Configuration File
To customize CORS settings, first publish the configuration file using the Artisan command:
php artisan config:publish cors
This creates a new file at config/cors.php containing all available CORS options.
Step 2: Understanding Configuration Options
Open config/cors.php and you’ll see the default configuration:
Let’s examine each option in detail:
<?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'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
];
Let’s examine each option in detail:
paths
Specifies which routes should have CORS enabled. The default [‘api/’, ‘sanctum/csrf-cookie’] applies CORS to all API routes and Laravel Sanctum’s CSRF cookie endpoint. Use [‘*’] to enable CORS for all routes.
'paths' => ['api/*', 'sanctum/csrf-cookie'],
// Or enable for all routes:
'paths' => ['*'],
// Or specify exact paths:
'paths' => ['api/users', 'api/products/*', 'webhooks/*'],
allowed_methods
Defines which HTTP methods are permitted in cross-origin requests. The wildcard [‘*’] allows all methods (GET, POST, PUT, DELETE, PATCH, OPTIONS).
'allowed_methods' => ['*'],
// Or restrict to specific methods:
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
allowed_origins
Specifies which domains are allowed to make cross-origin requests. The wildcard ‘*’ allows all origins, but this should never be used in production with credentials.
// Development - Allow all (not recommended for production):
'allowed_origins' => ['*'],
// Production - Specify exact origins:
'allowed_origins' => [
'https://example.com',
'https://app.example.com',
'http://localhost:5173', // For local development
],
allowed_headers
Defines which HTTP headers can be used in the actual request. The wildcard [‘*’] allows all headers.
'allowed_headers' => ['*'],
// Or specify exact headers:
'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept'],
supports_credentials
Determines whether cookies, authorization headers, or TLS client certificates can be included in cross-origin requests. Set to true when using session-based authentication or cookies.
'supports_credentials' => true,
Important: When supports_credentials is true, you cannot use wildcards (‘*’) in allowed_origins. You must specify exact origins.
allowed_origins_patterns
Use regular expressions to match multiple origins dynamically. For e.g.
'allowed_origins_patterns' => [
'/^https?:\/\/(.*\.)?example\.com$/', // Matches all subdomains of example.com
'/^http:\/\/localhost:\d+$/', // Matches localhost with any port
],
exposed_headers
Lists response headers that should be accessible to the client-side JavaScript code.
'exposed_headers' => ['X-Custom-Header', 'X-Total-Count'],
max_age
Specifies how long (in seconds) the browser can cache the preflight response. This reduces the number of preflight requests for repeated API calls.
'max_age' => 3600, // Cache for 1 hour
'max_age' => 86400, // Cache for 24 hours
Conclusion
Configuring CORS in Laravel 12 is simple thanks to the built-in middleware and cors.php configuration file. Whether you’re working on a SPA, mobile app, or external API integration, setting proper CORS rules ensures secure and smooth communication between your frontend and backend.
By following this step-by-step guide, you can:
- Enable CORS globally
- Restrict or allow specific domains
- Apply CORS to individual routes
- Customize allowed methods, headers, and credentials
Frequently Asked Questions
Q1: Do I need to install a package for CORS in Laravel 12?
No, Laravel 12 has built-in CORS support through the HandleCors middleware. You only need to publish and configure config/cors.php.
Q2: Why does my API work in Postman but not in the browser?
Postman doesn’t enforce CORS restrictions like browsers do. CORS is a browser-security feature. Test with actual browser requests to verify CORS configuration.
Q3: Can I use wildcards for allowed origins in production?
While technically possible, using ‘*’ for allowed origins is highly discouraged in production, especially with supports_credentials: true, as it creates security vulnerabilities.
Q4: What’s the difference between allowed_origins and allowed_origins_patterns? q
allowed_origins lists exact domain strings, while allowed_origins_patterns uses regular expressions to match multiple origins dynamically, useful for subdomains.
Q5: How do I fix “Response to preflight request doesn’t pass access control check”?
Ensure OPTIONS is in allowed_methods, HandleCors middleware is registered and runs early (use prepend), and your CORS configuration matches the request origin.