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

Technical writer at Laravel News, Developer Advocate at Treblle. API specialist, veteran PHP/Laravel engineer. YouTube livestreamer.

Cube

Laravel Newsletter

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

Laravel Forge logo

Laravel Forge

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

Laravel Forge
Tinkerwell logo

Tinkerwell

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

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
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
Bacancy logo

Bacancy

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

Bacancy
Lucky Media logo

Lucky Media

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

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
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
Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate logo

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate

Build your SaaS application in hours. Out-of-the-box multi-tenancy and seamless Stripe integration. Supports subscriptions and one-time purchases, allowing you to focus on building and creating without repetitive setup tasks.

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3 image

Herd Executable Support and Pest 3 Mutation Testing in PhpStorm 2024.3

Read article
Register now for Sentry Launch Week! image

Register now for Sentry Launch Week!

Read article
Hide and safeguard emails from bots with the Muddle Laravel package image

Hide and safeguard emails from bots with the Muddle Laravel package

Read article
Dynamic Cache, Database, and Mail Builders in Laravel 11.31 image

Dynamic Cache, Database, and Mail Builders in Laravel 11.31

Read article
PHPStan 2.0 is Here image

PHPStan 2.0 is Here

Read article
Run multiple CLI commands locally at once with Solo for Laravel image

Run multiple CLI commands locally at once with Solo for Laravel

Read article