Trouble getting CORS to work


#1

I’m trying to get an API working with Slim, and was having CORS issues. After some googling, I found a slightly more enhanced version of what’s recommended in the Slim documentation:

Request $request, Response $response, $next) {
    $route = $request->getAttribute('route');

    $methods = [];
    if (!empty($route)) {
            $pattern = $route->getPattern();

            foreach ($this->router->getRoutes() as $route) {
                    if ($pattern === $route->getPattern()) {
                            $methods = array_merge_recursive($methods, $route->getMethods());
                    }
            }
    } else {
            $methods = $request->getHeader('HTTP_ACCESS_CONTROL_REQUEST_METHOD');
//          $methods[] = $request->getMethod();
    }

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

    return $response
            ->withHeader('Access-Control-Allow-Origin', env('FRONTEND_DOMAIN'))
//		->withHeader('Access-Control-Allow-Methods', '*')
            ->withHeader('Access-Control-Allow-Methods', implode(',', $methods))
//          ->withHeader('Access-Control-Allow-Headers', 'content-type,authorization');
            ->withHeader('Access-Control-Allow-Headers', implode(',', $request->getHeader('access-control-request-headers')));
}

As you can see, I played around a bit with how to set the headers. But also, I had to modify the part that retrieves the methods as some of the OPTIONS calls made never caught a route, and thus never got any methods besides OPTIONS and failed.

This seems to work most of the time, but is failing now and then (in other’s people’s browsers, so I can’t test, and I also can’t replicate). It got me thinking if I’ve screwed up something in my app for why the suggested CORS method doesn’t work and thus had to modify it over.

Any advice on how to handle this or debug this would be great.

I did also try a third party package (https://github.com/tuupola/cors-middleware) but couldn’t get that working at all.


#2

Can you just try this CORS middleware first? Please tell me if it works for you.

// CORS preflight middleware
$app->add(function (Request $request, Response $response, $next) {
    if ($request->getMethod() !== 'OPTIONS' || php_sapi_name() === 'cli') {
        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;
});