tuupola / cors-middleware

PSR-7 and PSR-15 CORS middleware
MIT License
132 stars 16 forks source link

Upgrading to Slim 4, Running into problems with CORS #41

Closed kdoe13 closed 4 years ago

kdoe13 commented 4 years ago

First off, I've had great experiences using JWT-Auth and Basic-Auth, and I appreciate your time on these projects, so when I was having some issues with CORS, I was glad to come across this middleware, but I'm still having issues. I've simplified my project quite a bit to try to see if I can't figure out the problem, so here's what I have going on right now:

From my front-end server I'm building the request with the following javascript code: $.ajax({ method: "GET", url: "https:test-api:8890/settings/", contentType: "application/json", timeout: 5000, }).done(function (response) { resolve(response); }).fail(function (error) { logError(error, 'Api request ' + method + ' failed to ' + url); reject(Error('There was an issue interacting with the api')); });

My backend slim application is as follows: $app = \Slim\Factory\AppFactory::create(); $app->add(new \Tuupola\Middleware\CorsMiddleware); $app->addRoutingMiddleware; $app->get('/settings/, '\Dev\Middleware\UsersController:settings'); $app->run();

When I request GET /settings/ from the front-end server, I receive the following:

  1. Console output of has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  2. On network traffic, I get no Response headers, and I get an error that "Api request GET failed to /settings/ which is b/c the Ajax Request failed.

Now if I instead write in my .htaccess file the following, everything works fine, so for whatever reason the CorsMiddleware doesn't seem to be attaching those Headers like I'd expect. Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE" Header set Access-Control-Allow-Headers "Authorization, Content-Type"

I have been running Slim 3 with a custom CorsMiddleware setup but that essentially just adds these headers the same way and it works fine there, so I'm super confused...was hoping this was going to work for me but so far no luck. Thank you for any support you can give. Appreciate it.

tuupola commented 4 years ago

Maybe try to run with internal PHP server to see if your webserver is eating the headers. Just tested with Slim 4 and the middleware seems to work fine.

<?php

require __DIR__ . "/vendor/autoload.php";

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
use Tuupola\Middleware\CorsMiddleware;

$app = AppFactory::create();
$app->add(new Tuupola\Middleware\CorsMiddleware);

$app->get("/", function (Request $request, Response $response, array $args) {
    $response->getBody()->write("Here be dragons.");
    return $response;
});

$app->run();

Yields:

 $ curl --include http://0.0.0.0:8080  \
    --request OPTIONS \
    --include \
    --header "Access-Control-Request-Method: PUT" \
    --header "Origin: http://www.example.com"

HTTP/1.1 200 OK
Host: 0.0.0.0:8080
Date: Thu, 26 Sep 2019 09:35:22 GMT
Connection: close
X-Powered-By: PHP/7.3.9
Access-Control-Allow-Origin: http://www.example.com
Vary: Origin
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Content-type: text/html; charset=UTF-8
tuupola commented 4 years ago

Did some testing and noted that if I specifically call $app->addRoutingMiddleware(); like you do in the above example, this works:

$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->add(new Tuupola\Middleware\CorsMiddleware);

But if I change the order of the middlewares:

$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->add(new Tuupola\Middleware\CorsMiddleware);

I get a fatal error with status 200.

$ curl --include http://0.0.0.0:8080  \
    --request OPTIONS \
    --include \
    --header "Access-Control-Request-Method: PUT" \
    --header "Origin: http://www.example.com"

HTTP/1.1 200 OK
Host: 0.0.0.0:8080
Date: Thu, 26 Sep 2019 09:44:06 GMT
Connection: close
X-Powered-By: PHP/7.3.9
Content-type: text/html; charset=UTF-8

<br />
<b>Fatal error</b>:  Uncaught Slim\Exception\HttpMethodNotAllowedException: Method not allowed. in /Users/tuupola/Code/php/slim-4-cors/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php:94
...
kdoe13 commented 4 years ago

Ya that is working for me through curl as well, but not able to get it to work when I hit it from my AJAX request code....frustrating

tuupola commented 4 years ago

In general curl is the best tool for debugging. You can control exactly what is sent and also see exactly what is received. You could check from the browser console the request and response headers of the preflight (OPTIONS) request. Problem seems to lie somewhere in there.

tuupola commented 4 years ago

PS. When writing a comment, for codeblocks you can use triple ` ie ```.

kdoe13 commented 4 years ago

Ended up having to do with how I was initializing my App that for some reason broke in Slim 4 from Slim 3. Thanks for the help along the way!