skip to Main Content

We have deployed a Laravel 10 – React JS web application on windows server.

API is working, tried it on postman.
Web pages for our front-end is also working, except when executing api. It is showing a cors error below:

Access to XMLHttpRequest at ‘https://api.mydomain.com/sign-in’ from origin ‘https://webapp.mydomain.com’ 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.

I’m sure i have configured the .env and cors.php correctly, enabled cors middleware. Also, it is working on my local environment with just localhost:8000 and localhost:3000.

Is there anyone with same problem? How do you guys solve this?

Here’s the code:

cors.php

<?php

return [

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

    'allowed_methods' => ['*'],

    'allowed_origins' => [env('FRONTEND_URL', 'https://webapp.mydomain.com')],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

];

Laravel: .env

APP_URL=https://api.mydomain.com
FRONTEND_URL=https:/webapp.mydomain.com
SANCTUM_STATEFUL_DOMAINS=webapp.mydomain.com
SESSION_DOMAIN=mydomain.com

React: .env
VITE_API_BASE_URL=https://api.mydomain.com

web.config

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>

   code here...

    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="https://webapp.mydomain.com" />
                <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
                <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
                <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
    
  </system.webServer>

</configuration>

axios-client.js

import axios from 'axios';
import csrfCookie from './csrf-cookie';

const api = axios.create({
    baseURL: `${import.meta.env.VITE_API_BASE_URL}/api/v1`,
    withCredentials: true,
})

const web = axios.create({
    baseURL: `${import.meta.env.VITE_API_BASE_URL}`,
    withCredentials: true,
})

const apiBase = `${import.meta.env.VITE_API_BASE_URL}/api/v1`
const webBase = `${import.meta.env.VITE_API_BASE_URL}`

export { api, web, apiBase, webBase };

Signin code

import { api, web } from "../axios-client"
import csrfCookie from "../csrf-cookie"

        await csrfCookie().catch(err => {
            code here...
        })

        await web.post('/sign-in', formData)
            .then(async ({ data }) => {
                code here...
            })
            .catch(err => {
                code here...
            })
    }

2

Answers


  1. Chosen as BEST ANSWER

    I tried moving my customHeaders from React's web.config to Laravel's web.config. However, this resulted in a new error:

    The 'Access-Control-Allow-Origin' header contains multiple values 'https://webapp.mydomain.com, https://webapp.mydomain.com', but only one is allowed.

      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="https://webapp.mydomain.com" />
                <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
                <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" />
                <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
    

    When I removed the customHeaders from Laravel's web.config, it resulted in a "No Access-Control-Allow-Origin" error. Adding it back caused the multiple header values error again. So then I tried removing my front-end URL from the 'allowed_origins' in cors.php, which finally resolved the issue.

    cors.php

    'paths' => ['api/*', 'sanctum/csrf-cookie', 'sign-in', 'sign-out'],
    
    'allowed_methods' => ['*'],
    
    'allowed_origins' => [/*Removed frontend url here*/],
    
    'allowed_origins_patterns' => [],
    
    'allowed_headers' => ['*'],
    
    'exposed_headers' => [],
    
    'max_age' => 0,
    
    'supports_credentials' => true,
    

  2. You might consider creating middleware for custom header responses.

    class CorsMiddleware {
        public function handle($request, Closure $next)
        {
            //Intercepts OPTIONS requests
            if($request->isMethod('OPTIONS')) {
                $response = response('', 200);
            } else {
                // Pass the request to the next middleware
                $response = $next($request);
            }
    
            // Adds headers to the response
            $response->header('Access-Control-Allow-Methods', '*');
            $response->header('Access-Control-Allow-Headers', '*');
            $response->header('Access-Control-Allow-Origin', env('FRONTEND_URL', 'https://webapp.mydomain.com'));
            return $response;
        }
    }
    

    Then, apply this middleware to your API.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search