Ad

Preflight Headers Not As Expected

- 1 answer

I'm trying to send a request from an Angular 8 app to Laravel 5.8 Passport API, but without success. I mean, with only a limited success. When I set withCredientials into the Angular request to true, the Preflight headers are trying to see whether the API would return proper headers, including Access-Control-Allow-Credentials: true, but the response shows that there's no such header, even though I'm setting it into the backend.

If I don't set withCredentials, the response headers include Access-Control-Allow-Credentials: true, just as expected, but I need that response in the preflight response as well.

I have tried enveloping the preflight request case in separate block, using

    if (!$_SERVER['REQUEST_METHOD']=='OPTIONS')

and setting that header response explicitly, but without success as well. A side note is that requesting that same URL from Postman works as expected (ever since Postman doesn't mess with CORS).

The request is being fired from the following code snippet:

    await this.http.post(this.logInEndPoint, credentials, {
        headers: this.httpHeaders,
        withCredentials: true
    }).subscribe(async res => {
    ...

The CORS middleware looks as follows:

    $res->headers->set('Content-Type', 'application/json');
    $res->headers->set('Access-Control-Allow-Origin', 'http://127.0.0.1:4200');
    $res->headers->set('Access-Control-Allow-Credentials', 'true');
    $res->headers->set('Access-Control-Max-Age', '60');
    $res->headers->set('Access-Control-Allow-Headers', 'x-requested-with, Content-Type, origin, authorization, accept, client-security-token');
    $res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if (!$_SERVER['REQUEST_METHOD']=='OPTIONS') {
      $next($res);
    } else {
      return $res;
    }

And that's where I define the use of the CORS middleware api.php

    Route::middleware('web', 'json.response', 'cors')->group(function() {
       Route::post('login', '[email protected]');

    ...

I expect "Successfully logged in" message, but instead got Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/login' from origin 'http://127.0.0.1:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. in the Developer Tools.

Ad

Answer

After several days of struggling with that problem, I finally figured it out. If I have to summarize the majority of problems, related to Angular consuming Laravel APIs, I'd point out the header settings in the backend. For me it was somewhere within the custom CORS middleware.
If I have to be honest, I'm not sure what's exactly wrong in the configuration above (I guess it is in the Allow-Methods header), but I'd share how I fixed my issue.
First of all, I removed all the custom middlewares I made. I started using the Barry vd. Heuvel's CORS one, adding it for the API's group only. There, I changed the default configuration. I set allowOrigins to my Angular server URI and allowedMethods to the requests I'm expecting to use. After publishing the CORS configuration file, I made sure to run my Angular app on 127.0.0.1 (and not on localhost). The same I did for the Laravel server.
After running both the apps on one and the same IP address and using the new CORS middleware, everything ran smoothly and without problems.

Ad
source: stackoverflow.com
Ad