4,000 emails/month for free | Mailtrap sends real emails now!

Diving into Cross-Origin Resource Sharing

Published on by

Diving into Cross-Origin Resource Sharing image

Learn how to harness the power of Laravel CORS in this tutorial. Discover what it is and unlock its potential for seamless cross-origin resource sharing.

Laravel has supported CORS for quite a while; however, until more recent versions, it has been from third-party packages only. Let's dive into CORS in Laravel, what it is, and why it is important.

CORS stands for Cross-Origin Resource Sharing. It is a mechanism that allows you to make requests to a different domain than your own securely. It defines a set of headers the server can use to control which origins can access its resources. But what does this mean to you?

As someone who builds a lot of APIs, I am very used to CORS. It has become second nature at this point. Laravel, by default, has CORS support built in, where it will read from config/cors.php to programmatically build up the protection rules based on the values configured. Let's walk through the options in this file to see what they mean to us.

Paths

Our first option is paths, which by default has the following:

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

In this option we are telling the CORS middleware to match any requests listed here and allow CORS to proceed to the next check. If the incoming request does not match any pattern we add to our configuration, we will automatically block any requests from external hosts.

Methods

Our next option is the allowed methods, which by default is configured in the following way:

'allowed_methods' => ['*'],

By default Laravel will allow any method to be passed in externally, meaning that an API integration does not need any special considerations. You can be as strict or relaxed as you want here. This is entirely down to you. I usually keep the default here, as most of the APIs I typically build want complete external control in some respects. If we changed this to:

'allowed_methods' => ['GET', 'POST','PUT','PATCH'],

It would mean that we want to reject any external requests that are explicitly a DELETE request or a request not listed in the CORS configuration. If you have a public read-only API, you are more likely to configure this differently.

Origins

Next, we look at the allowed origins, which by default are configured like so:

'allowed_origins' => ['*'],

What we are saying by default is that we will allow connections or requests to come in from any origin (aka IP address or server). If we were building internal APIs, we would look to configure this to either an IP range or limit this to specific domains. This helps protect you against people making requests from locations you may not want them to. Again, if your API is public, you will likely keep this as it is. Please remember this setting should you have CORS issues when integrating with your API.

You can use an additional configuration part to be less specific and lean on regex matching more. This is the allowed origins patterns, where you can add regex to check the origin of a request to see if they are being accepted or rejected. By default, it is an empty array, as you will want to be careful here:

'allowed_origins_patterns' => [],

Headers

You can be as strict or as relaxed as you need to be with headers when it comes to CORS configuration. This part of the configuration allows you to set what headers are allowed from third-party origins when a request comes in. Let's say you want to be very specific so that external parties can only make requests in specific content types or enforce accepting particular content types. This is unlikely but a good example. In some APIs, especially a few years ago - I used to add application middleware that would check if they were accepting JSON and reject with a warning if it wasn't in place. We can do the same thing here - but for third parties only. The default in Laravel looks like the following, though:

'allowed_headers' => ['*'],

Exposing Headers

Exposing Headers is a funny one. Chances are you will not need it - but if you do, it will take ages to figure out that you need it! The default configuration looks like the following:

'exposed_headers' => [],

So to understand what to add here, if you need it, you need to understand what or who is integrating with you. Typically the CORS issues here would be related to browser rules with CORS and CORS requests, where headers are being stripped out as they are deemed unsafe. Let's say that you have headers that are non-default such as: X-VAPOR-ENCODE or X-GITHUB-ID or something to that effect, by default these will be stripped out on CORS requests, which could, in turn, could cause unintended side effects you were not aware of.

Max Age

We can configure how long clients can cache resources for using this option in the CORS configuration.

'max_age' => 0,

By default, we are configuring this so clients do not cache anything from our application. This, however, is flexible, as only integrations such as browsers will fully respect this.

Credentials

Finally, we have the support credentials option. This option, by default, is set to false:

'supports_credentials' => false,

What we are configuring here is, do we want to allow authentication from third-party origins. This is something to be very considerate about because if you set this to true, people can log in and get authentication details back. If we set this to true, then you will open yourself up for potential phishing attacks on your users, which can lead to further issues. If you have to set it to true, then ensure that the other options are precise so that you can control who can do this. The last thing you want to do is allow all requests from any origin that supports credentials!

This was only a walkthrough of what can be done with the configuration and what each option means to you and your application. Always ensure you are careful when configuring CORS configuration and rules because you do not want to open yourself and, by extension, your users up to any potential attacks due to the wrong configuration.

Steve McDougall photo

Educator and Content creator, freelance consultant, API evangelist

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Tinkerwell

Enjoy coding and debugging in an editor designed for fast feedback and quick iterations. It's like a shell for your application – but with multi-line editing, code completion, and more.

Visit Tinkerwell
Curotec logo

Curotec

World class Laravel experts with GenAI dev skills. LATAM-based, embedded engineers that ship fast, communicate clearly, and elevate your product. No bloat, no BS.

Curotec
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $3200/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit

The latest

View all →
Fair Queue Distribution with Laravel Balanced Queue image

Fair Queue Distribution with Laravel Balanced Queue

Read article
Migrating Laravel News from Laravel Forge to Cloud image

Migrating Laravel News from Laravel Forge to Cloud

Read article
Laravel News Is the Live Stream Partner for Laracon EU 2026 image

Laravel News Is the Live Stream Partner for Laracon EU 2026

Read article
Query Builder Expression Aliases in Laravel 12.48 image

Query Builder Expression Aliases in Laravel 12.48

Read article
Restrict User Actions with Time-Based Sanctions Using Laravel Prohibitions image

Restrict User Actions with Time-Based Sanctions Using Laravel Prohibitions

Read article
Laravel Invite Only Adds a Full User Invitation System with Tokens, Events, and Reminders image

Laravel Invite Only Adds a Full User Invitation System with Tokens, Events, and Reminders

Read article