Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

The 'Access-Control-Allow-Origin' header contains multiple values #63

Closed
mohagovmv opened this issue Aug 30, 2015 · 27 comments
Closed

The 'Access-Control-Allow-Origin' header contains multiple values #63

mohagovmv opened this issue Aug 30, 2015 · 27 comments

Comments

@mohagovmv
Copy link

I'm using AngularJS App on the client side to access Laravel API hosted on IIS 8.5.It works fine when client is hosted on same domain.But when hosted on different domain it gives following error.

XMLHttpRequest cannot load http://example.com/api. The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost, *', but only one is allowed. Origin 'http://localhost' is therefore not

Web.config:

<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1" stopProcessing="true">
                    <match url="^(.*)/$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Redirect" url="/{R:1}" redirectType="Permanent" />
                </rule>
                <rule name="Imported Rule 2" stopProcessing="true">
                    <match url="^" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php" />
                </rule>
            </rules>
        </rewrite>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Headers" value="Origin, Content-Type, Authorization, Accept, X-Request-With" />
                <add name="Access-Control-Allow-Methods" value="GET, POST, PUT,  DELETE, OPTIONS" />
                <add name="Access-Control-Allow-Credentials" value="true" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>
</configuration> 

Actual Response header:

Request Method:POST
Status Code:200 OK
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Origin, Content-Type, Authorization, Accept, X-Request-With
Access-Control-Allow-Methods:GET, POST, PUT,  DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost
Access-Control-Allow-Origin:*

Why 'Access-Control-Allow-Origin' echoed twice.
What is the right way to host API on IIS? Do I have to include headers in web.config file.

@marcelorl
Copy link

Same issue

@marcelorl
Copy link

Actually nothing related to the package.

It was a wrong usage of the middlewares.

This package works like a charm.

Thanks.

@sachintaware
Copy link

Can you update how the middleware usage was wrong,I am facing the same issue and I am using it in this way in my routes.php

      Route::group(['middleware' => 'cors'], function(){
             Route::post('/contactform','ContactController@sendContact');
     });

@marcelorl
Copy link

OOO shit, i'm really late right?

You are using OAuth right?

I hope you not suffered too much with this shit. haha

Actually your route is all right.
For me, the solution was in the Kernel.php file. Within the array $middleware, I had inserted this line:
\App\Http\Middleware\VerifyTokenOauth::class,

And how the comment is saying:

/**
     * The application's global HTTP middleware stack.
     *
     * @var array
     */

It is global, so I just took away this line from the array and everything worked.

Let us know if it worked or your solution, for sure other people will be interested to know the solution for this "fucking" issue. hahaha.

@sachintaware
Copy link

This is my middleware and I have added the cors to the route middleware.This is how it looks! I have desabled the csrf token validation and kept it live only for api routes with route middleware 'VerifyApi'

      /**
 * The application's global HTTP middleware stack.
 */
protected $middleware = [
    'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
    'Illuminate\Cookie\Middleware\EncryptCookies',
    'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
    'Illuminate\Session\Middleware\StartSession',
    'Illuminate\View\Middleware\ShareErrorsFromSession',
    //'App\Http\Middleware\VerifyCsrfToken',
];

/**
 * The application's route middleware.
 */

protected $routeMiddleware = [
    'auth' => 'App\Http\Middleware\Authenticate',
    'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
    'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
    'loginAuth'=>'App\Http\Middleware\LoginAuthentication',
    'VerifyApi'=>'App\Http\Middleware\VerifyApiRequest',
    'cors'=>'Barryvdh\Cors\Middleware\HandleCors'     //for CORS support
];

}

I have an issue created as I did not get concrete solution from previous threads #74

Please go through as I am still stuck at this

@marcelorl
Copy link

I got it.

That sucks.

Could you try to simulate the same request in a only php file (non laravel)?
And, try to simulate the request again, in a fresh laravel installation?

This message happens because in some place of your project or configuration you are running the header('allow-origin: *'); more than once.

But first of all, just try to do the tests I said and let us know what will happen to you.

@sachintaware
Copy link

Yes,you mean at the laravel side right? I already cross checked it. routes.php,index.php and .htaccess files for existing headers but they do not exist. as I am testing it on a kind of staging but demo server,I cannot have a fresh install. This issue does not occur on local as we know. So I am stumped now.I will try other ways and revert if I fix. Thanks for the help @marcelorl

@marcelorl
Copy link

Hmmmmm, so, you mean that the routes.php, index.php and .htaccess have no header() configuration right?

Could you try to simulate the request with a pure php file? A post request for example. Then you will know if it is something related to the server or with your application.

Good luck =/

@sachintaware
Copy link

if I get you right, you mean instead of hitting a route,I place a cors.php and add headers to it allowing access control origin.Then send a request to that cors.php. Right? Ok I did the dirty fix I did not want to and it works, I added the default headers

    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: ACCEPT, CONTENT-TYPE, X-CSRF-TOKEN");
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS, DELETE");

I know this is not safe,but I had make it work for obvious reasons. And I guess,if this works it has to be some issue at tbe app level. Correct me if wrong

Cheers @marcelorl

@marcelorl
Copy link

YEP, that is the point.

This is something with the APP and not with your server at all. But you said that in your localhost it works smoothly right?

Actually I don't recommend you to leave a cors.php file as a final solution and do the request in there, it was just a test. It would be a lot better you have it in your App.
If you may have this solution just for a while, I think it is ok, until you figure out what is happening.

Another test that could be done -> a fresh install of laravel (with this package, otherwise you will have a default CORS error ¬¬) in your server, then you will know if it is some configuration that you have done and you dont remember.

If, it still does not work, you could considerate to move the website that is pinging in your API to the same host. Thinking in RESTful, the API would be a sub-domain like:

http://sachintaware.com/user/2/edit -> requester
http://api.sachintaware.com/v1/user/2 - API

Maybe I went to far hahaha. Let me know your updates. =)

@sachintaware
Copy link

Ok,right now the website is on S3 so its already a subdomain calling a subdomain.
my application is at staging.example.com and my website is at testsite.example.com/site1.
I currently send a request like staging.example.com/contactform/ which is my route.

Fresh install would kill me right now,I will try and debug and keep install as last option.
Yes the headers are a temp fix as the app is not in production.
Will update you for sure.
Cheers @marcelorl

@marcelorl
Copy link

Hmmmmm I got it.

Np. When you figure out the problem I would love to know what was that.

I think that it's ok you leave the test like that, (for a while), just to do more productive things.

Good luck again =).

@ghost
Copy link

ghost commented Aug 28, 2016

same issue

@gabrielcornoiu
Copy link

Hi,

I would like to share with you how I fixed the same issue and hopefully it will be included in future releases.

I'm using laravel 5.2 and the problem is that laravel includes in the response headers the "Access-Control-Allow-Origin" and other headers like "Access-Control-Allow-Credentials", etc. but the CORS library doesn't overwrite them so the final response includes duplicated headers.

The fix was creating a middleware with the following lines which removes the laravel default headers before the CORS library sets the right ones:

    public function handle($request, Closure $next)
    {
        header_remove('Access-Control-Allow-Credentials');
        header_remove('Access-Control-Allow-Origin');

        return $next($request);
    }

Then add this middleware to the Kernel.php file, mine looks like this where the HttpHeaders is the middleware I created which contains the above header_remove lines:

    protected $middleware = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \App\Http\Middleware\HttpHeaders::class,
        \Barryvdh\Cors\HandleCors::class,
        ..............
    ];

It would be great if the CORS library first removes the headers that is setting before it sets the right ones.

Thanks,
Gabriel

@Vinlock
Copy link

Vinlock commented Jun 23, 2017

Your server must be adding the headers. I found that my nginx config in my docker container had add_header lines in it. Removing these fixed my problem.

@misog
Copy link

misog commented Oct 5, 2017

This issue is still present in v0.9.3

img

@marijnbakker2
Copy link

marijnbakker2 commented Sep 10, 2018

If anyone still runs into this issue, here's what happened for me;

I found out that I had set the 'Access-Control-Allow-Origin' in 2 different places. Removing the one that was not in my middleware fixed the issue for me.

Hope this helps someone!

@Metourni
Copy link

Metourni commented Jun 4, 2019

I have the same problem here.
I am using Laravel 5.8.0 and the version of "barryvdh/laravel-cors": "^0.11.3".
The CORS configuration in config.cors.php is :

//...
   'supportsCredentials' => true,
    'allowedOrigins' => ['*'],
    'allowedOriginsPatterns' => [],
    'allowedHeaders' => ['*'],
    'allowedMethods' => ['*'],
    'exposedHeaders' => [],
    'maxAge' => 0,

  • Kernel.php
// ...
'api' => [
            'throttle:60,1',
            'bindings',
            \Barryvdh\Cors\HandleCors::class,
        ],

// ...
 protected $middleware = [
        \App\Http\Middleware\CheckForMaintenanceMode::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\TrustProxies::class,

        \Barryvdh\Cors\HandleCors::class,
    ];

My angular application ran on the host http://localhost:4200.
The error message is :

supports:1 Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/sessions/1/supports' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:4200, *', but only one is allowed.

@ruannawe
Copy link

this solution resolve to me

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        header('Access-Control-Allow-Origin', '*');
        header('Access-Control-Allow-Methods', '*');
        header('Access-Control-Allow-Headers', '*');

        return $next($request);
    }
}

@nomikz
Copy link

nomikz commented Apr 12, 2020

I have absolutely the same issue. Trying to make spa authentication with vuejs on the front.
vue is on admin.backend.test while laravel is on backend.test.
I am using laravel 7 so cors is baked into the laravel.
Getting this error in browser console:
Reason: Multiple CORS header ‘Access-Control-Allow-Origin’ not allowed
Networks header is this
image
I've crawled the whole web and all the tutorials. Kinda very disappointed : )

@barryvdh
Copy link
Member

Well it looks like the first header is probably from this package, the second is added elsewhere (eg valet/Apache/nginx with some config file/.htaccess), or using pho headers yourself. Do you need this package at all? When your remove this package, is 1 of those 2 Allow Origin headers still addded?

@nomikz
Copy link

nomikz commented Apr 20, 2020

Thanks! I think Valet is adding the additional header.

@nomikz
Copy link

nomikz commented Apr 20, 2020

image

@barryvdh You were so right!
Thanks!

@barryvdh
Copy link
Member

Is that a default config? Or did that come with Valet?

@nomikz
Copy link

nomikz commented Apr 20, 2020

I have never had to change valet config. This is default valet config. It has been always adding access-control-allow-origin *.
I am on mac. I had to go /usr/local/etc/nginx/valet and in valet.config I removed all the lines where access-control-allow-origin * been added.
And now everything is working.

@Deme94
Copy link

Deme94 commented May 11, 2020

I got it.

That sucks.

Could you try to simulate the same request in a only php file (non laravel)?
And, try to simulate the request again, in a fresh laravel installation?

This message happens because in some place of your project or configuration you are running the header('allow-origin: *'); more than once.

But first of all, just try to do the tests I said and let us know what will happen to you.

That was my problem, I had header('allow-origin: *'); duplicated in bootstrap/app.php while using cors in kernel.php
Thank you so much!

@ComradePashka
Copy link

Hello guys!

Not an issue but little addition. Maybe it will save a lot of time for someone.

I had two web-sites with Laravel and Lumen for API and I have encountred same problem after upload them from local environment (locally all was working normally) to dreamhost and I almost gone completely craze because I triple checked everything, until finally found that they have additional .htaccess located not inside web-server documentroot but in user home directory!!!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests