Closed taiwanleaftea closed 3 years ago
Which method are you using to authenticate? Are you using Sanctum?
Yes, Sanctum. In Sanctums' cors config
'supports_credentials'
=> true,
headers received from nginx seems to be ok
HTTP/1.1 204 No Content Server: nginx/1.10.3 Date: Thu, 18 Jun 2020 10:22:48 GMT Connection: keep-alive Access-Control-Allow-Origin: http://localhost:3000 Access-Control-Allow-Credentials: true Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type Access-Control-Max-Age: 1728000 Content-Type: text/plain charset=UTF-8 Content-Length: 0
there are request headers:
Host: getcandy.local User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0) Gecko/20100101 Firefox/77.0 Accept: / Accept-Language: ru,ru-RU;q=0.8,en;q=0.5,en-US;q=0.3 Accept-Encoding: gzip, deflate Access-Control-Request-Method: GET Access-Control-Request-Headers: x-candy-hub,x-requested-with Referer: http://localhost:3000/login Origin: http://localhost:3000 DNT: 1 Connection: keep-alive Cache-Control: max-age=0
Have you added localhost:3000
to SANCTUM_STATEFUL_DOMAINS
and also if you're using localhost, make sure you set SESSION_DOMAIN
to an empty string.
config/sanctum.php
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost:3000,localhost,127.0.0.1,127.0.0.1:8000,::1')),
config/session.php
'domain' => env('SESSION_DOMAIN', null),
The variables are not set in the .env
In the Sanctums' documentation is written:
In addition, you should enable the withCredentials option on your global axios instance. Typically, this should be performed in your resources/js/bootstrap.js file: axios.defaults.withCredentials = true;
but I don't understand where this config is located.
Set SESSION_DOMAIN
to ""
in your .env file and see if that helps. Also make sure your SESSION_DRIVER
is set to cookie
Both not work. This one:
SESSION_DRIVER=cookie SESSION_LIFETIME=120 SESSION_DOMAIN=""
and this:
SESSION_DRIVER=cookie SESSION_LIFETIME=120 SESSION_DOMAIN=
Maybe is something wrong with X-CANDY-HUB request header, because Safari shows me this message in the console
Request header field X-CANDY-HUB is not allowed by Access-Control-Allow-Headers.
Could you perhaps take a look at this video I made? Just to ensure that you didn't skip any important steps. Remember to read the videos description too.
It's a realtime paced installation process that shows how to set up the API and Admin Hub.
If you still cannot make it work, could you maybe share the contents, preferably in a (private) Gist or similar, of the following files in the API:
config/cors.php
app/Providers/RouteServiceProvider.php
routes/api.php
.env
(stripped of credentials, ofc)And finally, the .env
you've created for the Admin Hub.
Just to ensure that you didn't skip any important steps
I use virtualbox instead of docker, and I found the difference. I copied from the docs (in hub .env and api.php) "login", but according to your video it must be "v1/login". Now I don't get the CORS error, but get another:
The GET method is not supported for this route. Supported methods: POST.
But I don't see any GET request in the network inspector (see screenshot).
I've attached files. This is a fresh Laravel installation for testing, so the files don't contain any confidential information.
env-api.txt cors.php.txt RouteServiceProvider.php.txt api.php.txt env-hub.txt
Here is the response from the API
{ "message": "The GET method is not supported for this route. Supported methods: POST.", "exception": "Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException", "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php", "line": 117, "trace": [ { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php", "line": 103, "function": "methodNotAllowed", "class": "Illuminate\Routing\AbstractRouteCollection", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php", "line": 40, "function": "getRouteForMethods", "class": "Illuminate\Routing\AbstractRouteCollection", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php", "line": 162, "function": "handleMatchedRoute", "class": "Illuminate\Routing\AbstractRouteCollection", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/Router.php", "line": 639, "function": "match", "class": "Illuminate\Routing\RouteCollection", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/Router.php", "line": 628, "function": "findRoute", "class": "Illuminate\Routing\Router", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Routing/Router.php", "line": 617, "function": "dispatchToRoute", "class": "Illuminate\Routing\Router", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", "line": 165, "function": "dispatch", "class": "Illuminate\Routing\Router", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 128, "function": "Illuminate\Foundation\Http\{closure}", "class": "Illuminate\Foundation\Http\Kernel", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", "line": 21, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 167, "function": "handle", "class": "Illuminate\Foundation\Http\Middleware\TransformsRequest", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php", "line": 21, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 167, "function": "handle", "class": "Illuminate\Foundation\Http\Middleware\TransformsRequest", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php", "line": 27, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 167, "function": "handle", "class": "Illuminate\Foundation\Http\Middleware\ValidatePostSize", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php", "line": 63, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 167, "function": "handle", "class": "Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/fruitcake/laravel-cors/src/HandleCors.php", "line": 57, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 167, "function": "handle", "class": "Fruitcake\Cors\HandleCors", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/fideloper/proxy/src/TrustProxies.php", "line": 57, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 167, "function": "handle", "class": "Fideloper\Proxy\TrustProxies", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php", "line": 103, "function": "Illuminate\Pipeline\{closure}", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", "line": 140, "function": "then", "class": "Illuminate\Pipeline\Pipeline", "type": "->" }, { "file": "/media/sf_www/getcandy/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php", "line": 109, "function": "sendRequestThroughRouter", "class": "Illuminate\Foundation\Http\Kernel", "type": "->" }, { "file": "/media/sf_www/getcandy/public/index.php", "line": 55, "function": "handle", "class": "Illuminate\Foundation\Http\Kernel", "type": "->" } ] }
This might seem trivial, but could you possibly try and move the registered routes in the RouteServiceProvider.php
above the $this->mapApiRoutes();
and $this->mapWebRoutes();
instead of the placing now?
And additionally, can you also share the config/sanctum.php
file?
move the registered routes in the RouteServiceProvider.php above the $this->mapApiRoutes(); and $this->mapWebRoutes();
The same error.
Looks good. I see an error on the sweet-jar.jpg. Could you try and open the hub in an incognito window?
And you don't have Auth::routes()
in your routes/web.php
?
I see an error on the sweet-jar.jpg. Could you try and open the hub in an incognito window?
The same error. As I can see, the sweet-jar.jpg is loaded twice: the first call to http://localhost:3000/sweet-jar.jpg returns 404 error, the second to http://localhost:3000/_nuxt/assets/images/sweet-jar.jpg returns the image.
And you don't have Auth::routes() in your routes/web.php?
I have default closure from Laravel, and nothing more:
Route::get('/', function () { return view('welcome'); });
Maybe it would be helpful, here is the output from php artisan route:list
It seems weird. There are no GET requests. Maybe it's related to your VirtualBox setup. Can you share details about it? Have you tried my Docker approach?
Virtualbox 6.1 with virtual host adapter. getcandy.local mapped to the IP of this adapter in /etc/hosts
In Virtualbox I have debian 9 with nginx, mariadb, elasticsearch, and php-fpm 7.4. Laravel 7.16.1.
In nginx config for Getcandy I've added following:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $http_origin;
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X-Candy-Hub,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X-Candy-Hub,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,X-Candy-Hub,If-Modified-Since,Cache-Control,Content-Type';
}
If remove it, and get CSRF token mismatch.
error.
CORS nginx config is discussed here https://gist.github.com/michiel/1064640
Have you tried my Docker approach?
I can try. Where can I find it?
If remove it, and get CSRF token mismatch. error.
Well, that at least states that you actually reach the Laravel instance and your requests aren't rewritten. I do believe that it's your Nginx configuration that is messing everything up.
You can try the configuration that I'm using in the Docker-setup instead: https://github.com/Repox/getcandy-docker/blob/master/docker/nginx/docker-vhost.conf
That configuration allows you to manage the CORS via the CORS package included in Laravel.
My complete Docker setup can be found here.
You can try the configuration that I'm using in the Docker-setup instead:
I tried your nginx config, and got CSRF token mismatch.
I can see two requests:
Can you try and empty the SESSION_DOMAIN setting (to ensure that it's null
and not an empty string)?
I removed SESSION_DOMAIN from .env, so it should be null
by default. Get CSRF token mismatch.
with your nginx config.
I'm running out of ideas. What's the content of your app/Http/Kernel.php
?
On Monday I'll install the docker version, and will check difference in nginx.conf
between my and docker version.
I don't think this is a nginx issue anymore. The "CSRF token mismatch" mismatch error indicates that you are providing a different X-XSRF-TOKEN than what Laravel is expecting. It's most likely something with your session configuration, but exactly what it is, is difficult for me to say.
Can you provide the VirtualBox image (if not a Vagrant provisioning)? I'm intrigued as to figuring out what's going on.
You are just running the hub locally with NPM and accessing at http://localhost:3000
, right? No virtual environment for the hub?
Any solution?
update config/cors.php to set supports_credentials = true solved this for me
Sounds like this can be resolved with the suggestion above, ultimately it doesn't seem like an issue with the hub, more to do with API configuration. Closing for now but feel free to reopen if you feel this needs further work.
Getcandy API installed local at http://getcandy.local Getcandy HUB installed on the same computer at http://localhost:3000
I can access the API via curl from the terminal.
When I open http://localhost:3000, I see the login form, but can't login because of the CORS error:
I tried Firefox 77.0.1 and Safari 13.1.1