Response Headers


#1

Getting:

Failed to load http://localhost:3030/api/auth/login: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:3000’ is therefore not allowed access.

I’m using the Cors middleware defined in the Slim docs. I don’t get any of the headers back that are set on the response.

Using Nuxt/Axios on client.

Headers added:

$response
    ->withHeader('Access-Control-Allow-Origin', 'http://localhost:3000, http://localhost:3030')
    ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization, Access, Host')
    ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');

Also worth noting, works fine with Postman.

I saw some similar posts but never really saw an actual solution.


#2

Hi! Can you please try this CORS middleware?

use Slim\Container;
use Slim\Http\Request;
use Slim\Http\Response;

// CORS preflight middleware
$app->add(function (Request $request, Response $response, $next) {
    if ($request->getMethod() !== 'OPTIONS') {
        return $next($request, $response);
    }
    
    $response = $next($request, $response);
    
    $response = $response->withHeader('Access-Control-Allow-Origin', '*');
    $response = $response->withHeader('Access-Control-Allow-Methods', $request->getHeaderLine('Access-Control-Request-Method'));
    $response = $response->withHeader('Access-Control-Allow-Headers', $request->getHeaderLine('Access-Control-Request-Headers'));

    return $response;
});

#3

I get this:
xhr.js:178 OPTIONS http://localhost:3030/api/auth/login 500 (Internal Server Error)
dispatchXhrRequest @ xhr.js:178
xhrAdapter @ xhr.js:12
dispatchRequest @ dispatchRequest.js:59
Promise.then (async)
request @ Axios.js:51
wrap @ bind.js:9
request @ auth.js:307
_callee$ @ local.js:65
tryCatch @ runtime.js:62
invoke @ runtime.js:296
prototype.(anonymous function) @ runtime.js:114
step @ asyncToGenerator.js:17
(anonymous) @ asyncToGenerator.js:28
Promise.then (async)
step @ asyncToGenerator.js:27
(anonymous) @ asyncToGenerator.js:35
F @ _export.js:36
(anonymous) @ asyncToGenerator.js:14
login @ local.js:90
login @ auth.js:170
_callee$ @ signin.vue?b6b8:53
tryCatch @ runtime.js:62
invoke @ runtime.js:296
prototype.(anonymous function) @ runtime.js:114
step @ asyncToGenerator.js:17
(anonymous) @ asyncToGenerator.js:35
F @ _export.js:36
(anonymous) @ asyncToGenerator.js:14
submit @ signin.vue?b6b8:66
submit @ signin.vue?3609:18
invoker @ vue.runtime.esm.js:2023
fn._withTask.fn._withTask @ vue.runtime.esm.js:1822
signin:1 Failed to load http://localhost:3030/api/auth/login: Response to preflight request doesn’t pass access control check: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:3000’ is therefore not allowed access. The response had HTTP status code 500.
createError.js:16 Uncaught (in promise) Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)

For some reason it causes the controller to 500.


#4

It turns out it was the exception I throw for invalid content. I guess the response from a custom error handler doesn’t pass through the cors middleware so I add it in the handler as well. shrug


#5

Cors I went with:

    $response = $response->withHeader('Access-Control-Allow-Origin', getenv('CLIENT_URL'))
        ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');

    if ($request->getMethod() === 'OPTIONS') {
        return $response->withStatus(200);
    }

    $response = $next($request, $response);

    return $response;

and add this in my invoke of my handler:

    $response = $this->addHeaders($response);

and this method

protected function addHeaders(Response $response)
{
    $response = $response->withHeader('Access-Control-Allow-Origin', getenv('CLIENT_URL'))
        ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
        ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    return $response;
}

In case anyone has these issues… also have to add them in your NotFoundHandler as well. Lesson learned!