neomerx / cors-illuminate

CORS (Cross-Origin Resource Sharing) support for Laravel and Lumen
Apache License 2.0
48 stars 6 forks source link

Configuration question #10

Closed LoveAndHappiness closed 8 years ago

LoveAndHappiness commented 8 years ago

Hello @neomerx,

I am trying your wonderful package, but it isn't working till now.

I have followed your instructions by the point and don't understand why I have trouble.

I have a fresh installation of Laravel 5.2.22 and a fresh installation of cors-illuminate here:

https://github.com/LoveAndHappiness/cors-illuminate-example

But, though I configured everything to my liking, I just don't get any headers in my responses, though I added cors to my global middleware.

If you want to reproduce it, just

  1. Clone the repository
  2. php artisan migrate, to migrate a BooksTable
  3. php artisan db:seed, to seed 10 books into the BooksTable
  4. php artisan serve to boot server
  5. Goto route http://localhost:8000/api/books and check the headers of the response.

Any suggestions?

neomerx commented 8 years ago

I'm using it with 5.2. I installed it on 5.2.3 (or something pre 5.2.22) and upgraded to latest Laravel. OK, I'll take a look closer to your example.

neomerx commented 8 years ago

I've checked your sample and it looks you successfully installed the package.

If you enable logs (in config/cors-illuminate.php set KEY_LOGS_ENABLED to true) you will find in logs

[2016-03-13 14:34:13] local.DEBUG: CORS analysis for request started.  
[2016-03-13 14:34:13] local.DEBUG: Request is not CORS (empty or same as server origin).  
[2016-03-13 14:34:13] local.DEBUG: CORS analysis for request completed.  

As for your question about CORS headers. You are making non cross origin request (not CORS). For this reason cross origin (CORS) headers are not added. If you want to see them try invoke it from let's say js app hosted on 4200 port.

neomerx commented 8 years ago

I've added more details to log. If you composer update your project to latest CORS-PSR7 you will see logs like

[2016-03-13 15:09:10] local.DEBUG: CORS analysis for request started.  
[2016-03-13 15:09:10] local.DEBUG: Request is not CORS (request origin is empty or equals to server one). {"request":null,"server":"[object] (Neomerx\\Cors\\Http\\ParsedUrl: http://localhost:8888)"} 
[2016-03-13 15:09:10] local.DEBUG: CORS analysis for request completed.  
neomerx commented 8 years ago

@LoveAndHappiness I'm closing the issue. If you feel it still exists or just want question me please don't hesitate to ask.

LoveAndHappiness commented 8 years ago

Well... I also see what the logs say.

Therefore I updated the the above github repository. Now it includes laravels debugbar and a polymer web component that makes an ajax request to my subdomain.

In the welcome view, I have two components that make an ajax request.

The one commented out, makes a GET request to "http://laravel5.dev/api/books". This one is working and does not require CORS.

The other one, not commented out, makes a GET request to "http://api.laravel5.dev/v1/books". This one is not working. Even with your package.

Since the request is from "http://laravel5.dev/" or "http://localhost:8000", and goes to "http://api.laravel5.dev/", it should be Cross Origin (cors), shouldn't it?

None the less, the logs say, that it isn't cors. So, maybe I just don't understand something profoundly, because in my understanding, a request from a domain to a subdomain, is a situation, that would require your package, wouldn't it?

Maybe you could have a look at my config file (cors-illuminate.php). Thanks a lot for your time and effort. I really appreciate that.

I am not sure how you would reproduce this error, since the application of subdomain routing depends on the development environment. I am using wamp and needed to edit my hosts file and add a server alias to my vhost file. Please ask ahead, if I can assist you with reproducing the error.

neomerx commented 8 years ago

What is in the logs? Can you please copy it here?

neomerx commented 8 years ago

The shortest way to play with CORS for you (I tried with your old app):

add in Http/routes.php the following line

Route::group(['middleware' => ['web']], function () {
    Route::get('api/books', 'Api\BooksController@index');
    // you already have update handler in your controller
    Route::patch('api/books/{id}', 'Api\BooksController@update');
});

Send PATCH http://localhost:8000/api/books/111 with no body and headers (I'm using postman).

You will got 400 error from CORS (origin is not allowed) and check logs CORS is working.

In config/cors-illuminate.php add all origins to allowed

    Settings::KEY_ALLOWED_ORIGINS => [
        '*' => true,
        ...
    ],

turn off (comment out) VerifyCsrfToken in \App\Http\Kernel::$middlewareGroups

Send PATCH again. You will got 200 response.

neomerx commented 8 years ago

Not all requests send between origins are CORS in terms of CORS spec. That's why if you send same with GET header Origin won't be sent and such a request won't be CORS.

LoveAndHappiness commented 8 years ago

Let me rephrase what I want to do.

I want to build a laravel application that consumes an api from a different origin. In my case just a subdomain like this "http://api.myproject.dev/v1/books".

I want to be able to make a GET request. But whenever I do, I get the error message:

XMLHttpRequest cannot load http://api.laravel5.dev/v1/books. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://laravel5.dev' is therefore not allowed access. The response had HTTP status code 400.

Therefore I need to enable "Cross Origin Resource Sharing (Cors)" or use JSONP. JSONP works like charm, but is only usable for GET requests. But for every other request I would like to use your package.

I followed your instructions for the Patch request like you suggested with your cors package. But in your example the request would have worked anyway, because it is made on the same domain, instead of the subdomain.. But I would rather use a GET/POST/PATCH request to my subdomain. But then I get the error:

[01:53:01] LOG.debug: Request is not CORS (request origin is empty or equals to server one).

So, how do I make a GET request to my subdomain 'http://api.myproject.dev' using your package? Just using the following code, did not work:

Settings::KEY_ALLOWED_ORIGINS => [
    '*'                        => true,
    'http://localhost'         => true,
    'http://some.disabled.com' => null,
],

Thank you for your time.

P.S. I updated my repository according to your instructions. Just have a look at the welcome view. https://github.com/LoveAndHappiness/cors-illuminate-example.git

neomerx commented 8 years ago

I want to build a laravel application that consumes an api from a different origin.

My package is for apps which provide api. Sorry I thought it was obvious.

I get the error message: XMLHttpRequest cannot load ...

it seems you try to consume it from JavaScript but not laravel

I don't understand what are you trying to build.

If you said you build

neomerx commented 8 years ago

Please provide server and client apps. You have given only server app (with the previous version I successfully made GET/POST/PATCH CORS). I got no idea how you make requests (client app) and what error messages you have in logs.

LoveAndHappiness commented 8 years ago

Here is the app that contains server code as well as client code

https://github.com/LoveAndHappiness/cors-illuminate-example

Everything from the client side that sends xml requests is in the welcome.blade.php view. Only thing that you need to do is to enable subdomain routing to be able to process the requests, send from the welcome view to the api.

I understand that in some cases client apps and server apps are completely separated. Not in this case, because it doesn't make any sense, if it is possible to use subdomain routing to separate server app from client app.

To say it bluntly: server app is processed under api.myproject.com and the client code on any other route. I am sorry if I can't explain it more clear than that. And it doesn't really matter anymore, because I just decided to stop using subdomain routing altogether, since I can't make cors make to work.

neomerx commented 8 years ago

Thanks for the complete demo. I'm going to look it very closely today.

neomerx commented 8 years ago

@LoveAndHappiness Sorry question about domain configuration. I can see it sends a request to laravel5.dev. How it should be api server on api.laravel5.dev and web page with 'Send Patch Request' button on laravel5.dev?

neomerx commented 8 years ago

It looks I've configured the app. I can receive some data reply from http://api.laravel5.dev:8000/api/books and I can load web page from http://localhost:8000/

When I load page I can see 19 requests (js, css, font, polymer html, png) + 1 xhr request with http code 200. The xhr request is sent to http://api.laravel5.dev:8000/v1/books however server configured as local host. So CORS sees: browser sends origin 'localhost', server config says 'localhost' cors layer says it's not cors. The problem is that your server CORS configuration doesn't match URL the server is working on.

I've noticed you missed the port in resources/views/welcome.blade.php and added port

<iron-ajax
    auto
    url="http://api.laravel5.dev:8000/v1/books"
    content-type="application/json"
    handle-as="json"
    on-response="handleResponse"
    last-response="@{{books}}">
</iron-ajax>

I've changed server origin in config/cors-illuminate.php

    Settings::KEY_SERVER_ORIGIN => [
        'scheme' => 'http',
        'host'   => 'api.laravel5.dev',
        'port'   => 8000,
    ],

and reloaded the page. What I saw in logs

local.DEBUG: CORS analysis for request started.  
local.DEBUG: Request is identified as a pre-flight CORS request.  
local.INFO: Request header is not allowed. Check config settings for Allowed Headers. {"header":"accept"} 
local.DEBUG: CORS analysis for request completed.  

OK, I enabled all headers

    Settings::KEY_ALLOWED_HEADERS => [
        Settings::VALUE_ALLOW_ALL_HEADERS => true,
    ],

Page reload => no error neither in browser no in logs. Logs says pre-flight request was OK (no request for actual data). I hit the 'Send Patch Request' button browser writes to log that request was sent to

OPTIONS /api/books/111 HTTP/1.1
Host: laravel5.dev

Note port was invalid. Of course no changes in server logs. I didn't figured out where should I fix that.

I think you need to apply fixes above locally and fix hopefully last bug with port.

Let me know how it goes.

neomerx commented 8 years ago

My humble opinion on this. I don't see much sense in putting polymer app in PHP. It not only creates unnecessary complexity but also drops possible RPS (request per second) for polymer files from let's say 20K for pure html/css/js to 1,5K (as of PHP + Laravel). With nginx (or whatever modern server you use) you can put them together with any path structure with or without sub-domains.

neomerx commented 8 years ago

@LoveAndHappiness I'm closing the issue. If you feel it still exists please don't hesitate contact me.