Laravel multiple domain origin CORS

12,765

Solution 1

You can define an array of origins you want to allow and then check the incoming request if its one of them:

public function handle($request, Closure $next)
{
    $allowedOrigins = ['example.com', 'example1.com', 'example2.com'];
    $origin = $_SERVER['HTTP_ORIGIN'];

    if (in_array($origin, $allowedOrigins)) {
        return $next($request)
            ->header('Access-Control-Allow-Origin', $origin)
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
            ->header('Access-Control-Allow-Headers', 'Content-Type');
    }

    return $next($request);
}

Solution 2

@thefallen 's answer works for me, also I had the @sergey 's same problem, I solved like this.

public function handle($request, Closure $next)
{

  $allowedOrigins = [env('FRONTEND_ENDPOINT', 'http://localhost:8080'), env('WORDPRESS_ENDPOINT', 'http://localhost'), env('EXTRA_ENDPOINT', 'http://127.0.0.1')];

  if($request->server('HTTP_ORIGIN')){
    if (in_array($request->server('HTTP_ORIGIN'), $allowedOrigins)) {
        return $next($request)
            ->header('Access-Control-Allow-Origin', $request->server('HTTP_ORIGIN'))
            ->header('Access-Control-Allow-Origin', '*')
            ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
            ->header('Access-Control-Allow-Headers', '*');
    }
  }


  return $next($request);

}

this way you can also just set the variables in .env file like this.

FRONTEND_ENDPOINT=http://localhost:8080
WORDPRESS_ENDPOINT=http://localhost
EXTRA_ENDPOINT=http://127.0.0.1:8080

Solution 3

You could just check what host you are on, and then send out the matching Access-Control-Allow-Origin just for that one.

$request->getHttpHost() will get you the host name that was used in the request - if you just need to differentiate based on that, we can probably ignore the other stuff that is also part of the origin (protocol, port) here, and simply make this something like

public function handle($request, Closure $next)
    {
        $origin = $request->getHttpHost() == 'localhost' ?
                    'http://localhost:4200' : 'http://api.example.com';

        return $next($request)
            ->header('Access-Control-Allow-Origin', $origin)
            ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
            ->header('Access-Control-Allow-Headers', 'Content-Type');
    }

Of course you can make this more "sophisticated", if you need this for more possible origins (like match the host name against an array of possible values, take protocol and port into account to if necessary), but if you just need these two for now, that should basically do.

Share:
12,765
Sergey
Author by

Sergey

Updated on July 28, 2022

Comments

  • Sergey
    Sergey almost 2 years

    I want to allow two domains for CORS in my laravel to be able work with it locally and on the server, thus I don't wan't to expose my app to any domain. That is shat I have for now

    public function handle($request, Closure $next)
        {
            return $next($request)
                ->header('Access-Control-Allow-Origin', 'http://localhost:4200')
    //            ->header('Access-Control-Allow-Origin', 'http://api.example.com')
                ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE')
                ->header('Access-Control-Allow-Headers', 'Content-Type');
        }
    

    I'm not able to do it neither as I've commented nor as an array

  • Sergey
    Sergey over 5 years
    That works, however my Dingo Api become broken when I access my route in browser. It says {"message":"Undefined index: HTTP_ORIGIN","status_code":500}
  • thefallen
    thefallen over 5 years
    @Sergey, strange, maybe you could try $request->header('host') or $_SERVER['HTTP_REFERER'] instead of $_SERVER['HTTP_ORIGIN']?
  • skm
    skm about 4 years
    @thefallen Do I need to create a new middleware to add this code ?
  • thefallen
    thefallen about 4 years
    @skm yes, that would be the better approach. You could also make it part of the EncryptCookies or VerifyCsrfToken class if you have the web middleware on all of your routes, but a new middleware is what I would recommend.
  • gaba
    gaba over 3 years
    Hey man hanks for your answer it helped me. But i noticed you have duplicate lines here. Was it by mistake? ->header('Access-Control-Allow-Origin', $request->server('HTTP_ORIGIN')) ->header('Access-Control-Allow-Origin', '*')
  • Kamlesh
    Kamlesh over 3 years
    where to implement this solution, file path??
  • thefallen
    thefallen over 3 years
    @Kamlesh its a middleware.
  • Kamlesh
    Kamlesh over 3 years
    @thefallen Kindly suggest, in which middleware should i add this solution? Thanks in advance :)
  • thefallen
    thefallen over 3 years
    @Kamlesh best make a new one called CORS, so its a single purpose and you know what it does.
  • Kamlesh
    Kamlesh over 3 years
    Ok, I will try it tonight, thanks @thefallen :)
  • Hashim Aziz
    Hashim Aziz about 2 years
    Didn't work for me in Laravel 8, even after running php artisan optimize:clear/