Setting up CORS

CORS - Cross origin resource sharing

A good flowchart for implementing CORS support Reference:

CORS server flowchart

You can test your CORS Support here: http://www.test-cors.org/

You can read the specification here: https://www.w3.org/TR/cors/

The simple solution

For simple CORS requests, the server only needs to add the following header to its response:

  1. Access-Control-Allow-Origin: <domain>, ...

The following code should enable lazy CORS.

  1. $app->options('/{routes:.+}', function ($request, $response, $args) {
  2. return $response;
  3. });
  4. $app->add(function ($request, $handler) {
  5. $response = $handler->handle($request);
  6. return $response
  7. ->withHeader('Access-Control-Allow-Origin', 'http://mysite')
  8. ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
  9. ->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
  10. });

Add the following route as the last route:

  1. <?php
  2. use Slim\Exception\HttpNotFoundException;
  3. /*
  4. * Catch-all route to serve a 404 Not Found page if none of the routes match
  5. * NOTE: make sure this route is defined last
  6. */
  7. $app->map(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], '/{routes:.+}', function ($request, $response) {
  8. throw new HttpNotFoundException($request);
  9. });

Access-Control-Allow-Methods

The following middleware can be used to query Slim’s router and get a list of methods a particular pattern implements.

Here is a complete example application:

  1. <?php
  2. use Slim\Factory\AppFactory;
  3. use Slim\Routing\RouteContext;
  4. require __DIR__ . '/../vendor/autoload.php';
  5. $app = AppFactory::create();
  6. // This middleware will append the response header Access-Control-Allow-Methods with all allowed methods
  7. $app->add(function($request, $handler) {
  8. $routeContext = RouteContext::fromRequest($request);
  9. $routingResults = $routeContext->getRoutingResults();
  10. $methods = $routingResults->getAllowedMethods();
  11. $response = $handler->handle($request);
  12. $response = $response->withHeader('Access-Control-Allow-Methods', implode(",", $methods));
  13. return $response;
  14. });
  15. // The RoutingMiddleware should be added after our CORS middleware so routing is performed first
  16. $app->addRoutingMiddleware();
  17. $app->get("/api/{id}", function($request, $response, $arguments) {
  18. // ...
  19. });
  20. $app->post("/api/{id}", function($request, $response, $arguments) {
  21. // ...
  22. });
  23. $app->map(["DELETE", "PATCH"], "/api/{id}", function($request, $response, $arguments) {
  24. // ...
  25. });
  26. // Pay attention to this when you are using some javascript front-end framework and you are using groups in slim php
  27. $app->group('/api', function () {
  28. // Due to the behaviour of browsers when sending PUT or DELETE request, you must add the OPTIONS method. Read about preflight.
  29. $this->map(['PUT', 'OPTIONS'], '/{user_id:[0-9]+}', function ($request, $response, $arguments) {
  30. // Your code here...
  31. });
  32. });
  33. $app->run();