Core Middleware do not works for me

I am using this middleware for slim3 https://github.com/tuupola/cors-middleware

Here is my code to enable CORS Middleware

and here is my API

I am testing my API
https://flextype.org/api/delivery/entries?id=en&token=1a48b9de0494240759c6f85366aaa53d

with https://reqbin.com and I don’t see CORS unfortunately.

Server: nginx/1.14.1
Date: Sun, 23 Feb 2020 17:00:17 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Set-Cookie: PHPSESSID=a666c631f8bf297ae47dc4268ced67cc; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Encoding: gzip

because of this issue, I can’t use my API in js app’s: https://svelte.dev/repl/e25e8814cc064868b67dad11c90ed029?version=3.19.0

any ideas why it is so ?

Access to fetch at 'https://flextype.org/api/delivery/entries?id=en&token=1a48b9de0494240759c6f85366aaa53d' 
from origin 'null' has been blocked by CORS policy: 
The 'Access-Control-Allow-Origin' header contains the invalid value ''. 
Have the server send the header with a valid value, or, if an opaque 
response serves your needs, set the request's mode to 'no-cors' to 
fetch the resource with CORS disabled.

The ‘Access-Control-Allow-Origin’ header contains the invalid value ‘’.

Please check your CORS preflight request routes and the CORS preflight response headers for invalid values.

my data is not valid ? or this $app->add(new CorsMiddleware()); not enough ?

According to the error message this is not enough, because the origin value cannot be empty.

Try this:

$app->add(new CorsMiddleware([
    "origin" => ["*"],
    "methods" => ["GET", "POST", "PUT", "PATCH", "DELETE"],
    "headers.allow" => [],
    "headers.expose" => [],
    "credentials" => false,
    "cache" => 0,
]));

This will change the response header Access-Control-Allow-Origin to *.

@odan

I was trying this new example of using Tuupola\Middleware\CorsMiddleware but I still do not see headers, so I don’t know what is wrong really there, and how it will work then on live.

So. I am trying example from Slim 3 doc about CORS, for me it works:

API request:
https://test.flextype.org/api/delivery/entries?id=home&token=6d3356131d1bac120a21362a7bac8f42

Postman says it is ok, as I understand:

Svelte fetch, works:

but is it ok ? please review my code:

The response headers are looking good

but is it ok ? please review my code:

Honestly, I’m not a big fan of this fallback solution because it never works for me:

$app->options('/{routes:.+}', function ($request, $response, $args) {...

and

$app->map(['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], '/{routes:.+}', function($req, $res) {...

How I solved it:

  1. Remove all catch-all routes
  2. Implement your own CorsMiddleware
  3. Use explicit routes for all OPTIONS routes / CORS preflight requests
  4. If you send Authorization headers like Authorization: Bearer 12345 you also have to return a Access-Control-Allow-Credentials: true in your response header.

Here is my blog post: https://odan.github.io/2019/11/24/slim4-cors.html

Thanks, but it is for Slim4. I think it is may not work In Slim 3, can you help, with this for Slim3 ? what are differents there ?

The difference is that Slim 3 has no PSR-15 MiddlewareInterface. But you can rewrite it to a callable middleware like this: https://github.com/odan/prisma/blob/master/src/Middleware/CorsMiddleware.php

Okey, I am was trying to create and use as middleware, but then I think … can we do it just like this ?

$app->get('/api/delivery/entries', function (Request $request, Response $response) use ($flextype) {

...

// Return response
return $response->withJson($data, $response_code)
                ->withHeader('Access-Control-Allow-Origin', '*')
                ->withHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Accept, Origin, Authorization')
                ->withHeader('Access-Control-Allow-Methods', 'GET');
});

Postman says that headers are okey, at least I see them.

what do you think @odan ?

or even just

return $response
       ->withJson($data, $response_code)
       ->withHeader('Access-Control-Allow-Origin', '*');

No this is not enough, because you would have

  • to much duplicated code
  • incorrect / missing / invalid response headers
  • no CORS preflight requests routes (OPTION requests)

… and I think, it will not work.

seems it is works :slightly_smiling_face:
https://test.flextype.org/api/delivery/entries?id=movies&args[]&token=6f047babd1894064fbf7662080a9a2f0

I don’t know another way to test it :face_with_monocle: fetch works okey for this request