Angular CORS requests do not support Laravel server but preflight looks good

Long story short, I am posting data from Angular to Laravel server. OPTIONS / preflight requests look good, but the subsequent POST does not suggest that the Access-Control-Allow-Origin header is missing from the requested resource.

I am using Laravel 5 with Angular 1.2.26. More documentation on middleware can be found here: https://laracasts.com/discuss/channels/requests/laravel-5-cors-headers-with-filters .

Laravel middleware:

public function handle($request, Closure $next)
    {
        return $next($request)->header('Access-Control-Allow-Origin' , 'http://laravel.app:8001')
            ->header('Access-Control-Allow-Credentials', 'true')
            ->header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE')
            ->header('Access-Control-Allow-Headers', 'Content-Type, Accept, Authorization, X-Requested-With')
            ->header('Access-Control-Max-Age', '28800');
    }

      

Angular config - I've tried with different combinations of commented code, same results every time:

$httpProvider.defaults.useXDomain = true;
    //$httpProvider.defaults.withCredentials = true;
    //delete $httpProvider.defaults.headers.common["X-Requested-With"];
    //$httpProvider.defaults.headers.common["Accept"] = "application/json";
    //$httpProvider.defaults.headers.common["Content-Type"] = "application/json";

      

Pre-flight / OPTIONS:

Remote Address:127.0.0.1:8000
Request URL:http://laravel.app:8000/api/v1/authentication/login
Request Method:OPTIONS
Status Code:200 OK

Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:laravel.app:8000
Origin:http://laravel.app:8001
Referer:http://laravel.app:8001/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36

Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type, Accept, Authorization, X-Requested-With
Access-Control-Allow-Methods:POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin:http://laravel.app:8001
Access-Control-Max-Age:28800
Allow:GET,HEAD,POST
Cache-Control:no-cache
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/html; charset=UTF-8
Date:Mon, 24 Nov 2014 16:01:57 GMT
Server:nginx/1.6.2
Set-Cookie:laravel_session=blahblah; expires=Mon, 24-Nov-2014 18:01:57 GMT; Max-Age=7200; path=/; httponly
Set-Cookie:XSRF-TOKEN=blahblah; expires=Thu, 01-Jan-1970 00:02:00 GMT; Max-Age=-1416844797; path=/; httponly
Transfer-Encoding:chunked

      

POST:

Remote Address:127.0.0.1:8000
Request URL:http://laravel.app:8000/api/v1/authentication/login
Request Method:POST
Status Code:500 Internal Server Error

Request Headers
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:47
Content-Type:application/json;charset=UTF-8
Host:laravel.app:8000
Origin:http://laravel.app:8001
Referer:http://laravel.app:8001/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36

Request Payload
{email: "x", password: "x", rememberMe: false}
email: "x"
password: "x"
rememberMe: false

Response Headers
Cache-Control:no-cache
Connection:keep-alive
Content-Type:text/html; charset=UTF-8
Date:Mon, 24 Nov 2014 16:01:57 GMT
Server:nginx/1.6.2
Transfer-Encoding:chunked

      

+3


source to share


4 answers


After going through the VerifyCsrfToken middleware, I established that this is indeed a token mismatch.

The reason is that Angular did not feed the CSRF token via the header or via a parameter in the message. It worked for GET and OPTIONS requests because they don't validate the token.

So, I went through Angular and there is documentation on XSRF security (see https://docs.angularjs.org/api/ng/service/ $ http) and a lot of discussion there on how to add the relevant headers (for example https: // github .com / angular / angular.js / issues / 5122 # issuecomment-36157820 ).



I haven't had a chance to follow along as I need my project to move and my particular use case is allowing me to get away with disabling VerifyCsrfToken as I only need CORS during development.

But hopefully this will give someone else a starting point for a more complete solution to this problem.

+3


source


I'm not sure if this is an issue with Laravel and the VerifyCsrfToken middleware or not, but the root cause of my problem was that the CSRF token validation failed. When the error was cleared, the new headers were not included. I don't understand how it goes, maybe it is, but still after I removed the VerifyCsrfToken from the middleware stack everything lit up.



+2


source


I had a problem with this. If you use the middleware to set headers, but create a new controller Response, Response::json()

, Response::make()

etc. On the controller, this new object will not receive the headers set by the middleware.

0


source


I had the same problem. In CORS middleware add the following header.

public function handle($request, Closure $next)
{
    //All the domains you want to whitelist
    $trusted_domains = ["http://localhost:4200", "http://127.0.0.1:4200", "http://localhost:3000", "http://127.0.0.1:3000"];
    if (isset($request->server()['HTTP_ORIGIN'])) {
        $origin = $request->server()['HTTP_ORIGIN'];

        if (in_array($origin, $trusted_domains)) {
            header('Access-Control-Allow-Origin: ' . $origin);
            header('Access-Control-Allow-Headers: Origin, Content-Type, Authorization, X-Auth-Token,x-xsrf-token');
            header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS, PUT, DELETE');
        }
    }
    return $next($request);
}

      

0


source







All Articles