DEV Community

Cover image for Resolve "Blocked by CORS Policy: No 'Access-Control-Allow-Origin'" in Laravel
Roberto B.
Roberto B.

Posted on

Resolve "Blocked by CORS Policy: No 'Access-Control-Allow-Origin'" in Laravel

If your frontend and Laravel backend are on different domains, you’ve probably hit the dreaded CORS policy error.
This article will show you how to configure your Laravel application to allow cross-origin requests and get your API running smoothly.

The CORS issue

When building a Laravel-based backend and serving a frontend from a different domain, one common error developers encounter is the CORS (Cross-Origin Resource Sharing) policy error, which looks like this:

Access to XMLHttpRequest at 'https://my-home.test/sb-json' from origin 'https://app.storyblok.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Enter fullscreen mode Exit fullscreen mode

This error occurs because modern browsers block requests from one origin (your frontend domain) to another (your Laravel backend) unless the backend explicitly allows cross-origin requests.

Understanding CORS

CORS is a security feature implemented in browsers to prevent unauthorized websites from sending HTTP requests to your server. It controls how web pages make requests across different domains. The browser will block the request if the backend doesn't send the appropriate headers.

To fix this, the server (in this case, your Laravel application) must allow requests from your frontend domain.

Scenario

Let's say you're building a frontend logic (Vue.js or React app) hosted on https://app.storyblok.com and making API requests to your Laravel backend hosted on https://my-home.test. Due to the cross-origin nature of these requests, your frontend is blocked from interacting with the backend unless proper CORS headers are sent.

I encountered this issue customizing a Storyblok application when adding a Multi Options field and setting the Source to External JSON. This configuration triggers an HTTP request from a page served by the app.storyblok.com domain to a service at a different URL (not app.storyblok.com). While this is a specific scenario, it’s a common issue for anyone hosting the frontend on one domain and the backend on another.

Solving the CORS Issue

There are two main ways to resolve this issue:

  1. Configure CORS at the Web Server Level
  2. Handle CORS in Laravel (Application Level)

Both approaches aim to set three key HTTP headers correctly:

  • Access-Control-Allow-Origin: Specifies the allowed frontend domain, for example, 'https://app.storyblok.com'.
  • Access-Control-Allow-Methods: Defines the HTTP methods that are permitted, such as 'GET, POST, OPTIONS'.
  • Access-Control-Allow-Headers: Lists the additional headers allowed, for example, 'Origin, Content-Type, Accept, Authorization'.

Setting these headers correctly is essential, regardless of your backend framework or language. Whether your backend is built with Django, Express.js, or any other framework, solving CORS issues requires configuring these headers on the server.

In this article, we’ll focus on Laravel's capabilities for easily managing these headers and effectively resolving CORS issues.

So, if you use Nginx or Apache, you can set these three headers in the configuration.
Or, if you want to set these headers at the application level, you can set them via Laravel configuration, following the next steps.

Handle CORS in Laravel (Application Level)

Laravel offers built-in support for handling CORS through the HandleCors middleware. This approach is often more flexible and maintainable, especially if you're working in a shared hosting environment where you may not have access to the server configuration.

Under the hood, the Laravel Framework uses the package https://github.com/fruitcake/php-cors to manage the Cors Headers correctly.

Here’s how you can solve the CORS issue within Laravel itself: you need to change the default values of the HandleCors middleware. By default the options doens't allow HTTP call from a frontend delivered by a different domain.
To customize the options you have to "publish" the Cors configuration in your config directory so that yo can change the options.

php artisan config:publish cors
Enter fullscreen mode Exit fullscreen mode

This will create the config/cors.php file with the default values in your application.

Open the config/cors.php file and adjust the settings.

The use case we want to set up as an example is:

  • we want to allow the JavaScript frontend HTTP call from the app.storyblok.com hostname;
  • we want to allow the HTTP GET method;
  • we want to enable the access only for the /sb-json path. With these requirements, you can edit the value for paths, allowed_methods, and allowed_origins:
<?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' => ['sb-json'],
    'allowed_methods' => ['GET'],
    'allowed_origins' => ['https://app.storyblok.com'],
    'allowed_origins_patterns' => [],
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => false,
];
Enter fullscreen mode Exit fullscreen mode

This will allow cross-origin requests from https://app.storyblok.com to the Laravel backend. You can also modify the allowed_headers, and other options as needed.

References

Conclusion

CORS is a crucial security feature, but it can be a challenge when your frontend and backend are served from different domains. In Laravel, you can solve this by configuring CORS either at the web server level or within the application itself. The built-in middleware makes it easy to customize CORS settings to meet your project’s needs.

By following the steps above, you’ll be able to resolve the CORS error and enable seamless communication between your frontend and Laravel backend.

Happy coding!

Top comments (1)

Collapse
 
dipanjan profile image
Dipanjan Ghosal

Good article, thanks!
To anyone still facing issues on this, make sure you don't have any trailing slashes '/' after your urls for 'allowed_origins'. Lost a lot of time and energy on that lol.