beyondcode / laravel-websockets

Websockets for Laravel. Done right.
https://beyondco.de/docs/laravel-websockets
MIT License
5.08k stars 628 forks source link

Laravel 7 - Authentication problem on websocket dashboard #438

Closed klaasnicolaas closed 4 years ago

klaasnicolaas commented 4 years ago

I have Laravel Websockets running on Laravel 7 (thanks to the changes in this fork: https://github.com/beyondcode/laravel-websockets-demo/pull/12) but I get an error 500 in my console when I connect in the websocket dashboard (/ laravel-websockets).

image

I can confirm that the underlying websocket server has continued to work fine, because my test events are still arriving. However, this error message is purely at the dashboard what @beyondcode made.

In addition, I see the error message below in my laravel.log: [2020-08-05 10:29:53] local.ERROR: Trying to get property 'key' of non-object {"userId":1,"exception":"[object] (ErrorException(code: 0): Trying to get property 'key' of non-object at /var/www/mission-control/vendor/beyondcode/laravel-websockets/src/Dashboard/Http/Controllers/AuthenticateDashboard.php:22) [stacktrace]

Is it possible that someone has already experienced this problem and / or knows a solution?

klaasnicolaas commented 4 years ago

At some point it was for me also no longer possible to connect via the dashboard to the websocket server 😢 image

But after a lot of debugging and commenting one line in the file dashboard.blade.php, was it possible for me to connect again.

this.pusher = new Pusher(this.app.key, {
    wsHost: this.app.host === null ? window.location.hostname : this.app.host,
    wsPort: this.port === null ? 6001 : this.port,
    // wssPort: this.port === null ? 6001 : this.port,    <--- comment this line
    wsPath: this.app.path === null ? '' : this.app.path,
    disableStats: true,
    authEndpoint: '/{{ request()->path() }}/auth',
    auth: {
        headers: {
            'X-CSRF-Token': "{{ csrf_token() }}",
            'X-App-ID': this.app.id
        }
    },
    enabledTransports: ['ws', 'flash']
});
fylzero commented 4 years ago

Just pulled down a clone of the forked repo and couldn't replicate the error.

I'm running Laravel Valet and using SQLite for my DB. Here are my setup steps...

git clone git@github.com:fylzero/laravel-websockets-demo.git cd laravel-websockets-demo git checkout update-to-laravel-7 cp .env.example .env touch database/database.sqlite Open .env file and set APP_URL=http://laravel-websockets-demo.test and DB_CONNECTION=sqlite then save Commented out DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD composer install composer update npm install npm audit fix php artisan key:generate php artisan migrate:fresh --seed php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config" php artisan websockets:serve Open http://laravel-websockets-demo.test and register a user Open http://laravel-websockets-demo.test/laravel-websockets in a new tab Select the app "Laravel Websockets" Click connect Type messages into the chat window @ http://laravel-websockets-demo.test/

Everything seems to be working, no errors in the console for either page for me.

fylzero commented 4 years ago

Are you sure App is selected properly? I tried refreshing the page to see what would happen if app was not selected and it gave me a Cannot read property 'key' of null message. Different than what you have but figured I'd double-check with you.

klaasnicolaas commented 4 years ago

I'm sure I've done everything as I should, but will try again (I've really cloned your fork 100x), setting everything up through your step-by-step plan 😉

klaasnicolaas commented 4 years ago

I tried but unfortunately I get the same problem as with: https://github.com/beyondcode/laravel-websockets/issues/438#issuecomment-669192280

failed: WebSocket is closed before the connection is established.

If I then place the line in a comment again, it is possible to connect. However, only the event log works then, sending events and statistics give an error message or do nothing. 🤔

fylzero commented 4 years ago

@klaasnicolaas I got the 500 error to show. Seems to happen after running composer update. I've seen elsewhere that Pusher can't be updated for this to work? No idea if that is true but we might have to limit the allowable installed version of Pusher. I'll keep looking at it.

The other error WebSocket is closed before the connection is established. I actually ran into this before just trying to install this package on Laravel 7 outright... I had to upgrade this, in fact, to get rid of that error. Couldn't find what was causing it but it seemed to be environment or setup step related since I was able to get it consistently running with this upgrade path.

rennokki commented 4 years ago

I am using the same setup and works fine. The line in the controller refers to the App Key, which is defined in the config/websockets.php file. Are you sure that the config file has the same structure as this:https://github.com/beyondcode/laravel-websockets/blob/1.4.1/config/websockets.php#L26-L33

If it's missing the key attribute, this causes the issue.

fylzero commented 4 years ago

@rennokki If you guys are following my instructions above the PUSHER_APP_KEY, etc. is already set in the .env.example so copying that should be populating that. I don't think that is the issue.

The beyondcode/laravel-websockets package itself has a compser.json that is allowing Pusher to update to v4 where this repo I think expects v3. I could be wrong but that is my current suspicion.

I can tell you this. If you follow the instructions above and don't execute composer update this seems to work fine without the 500 error. That doesn't solve the bug though.

fylzero commented 4 years ago

@klaasnicolaas Do me a favor. Follow the instructions I posted, exactly. Without doing a composer update ...then let me know if the 500 error goes away. I'm betting something, likely Pusher, being updated is causing this error. Which means a bug may need to be submitted to beyondcode/laravel-websockets.

rennokki commented 4 years ago

@fylzero can u give me the installed versions of laravel/framework, laravel-websockets and pusher if u run $ composer show ? Also, try upgrading to 1.6.x

fylzero commented 4 years ago

laravel/framework: versions : v5.7.15 beyondcode/laravel-websockets: versions : dev-master

Right, duh. I forgot you need to execute composer update to update Laravel in the composer.lock as well.

Post update I get:

laravel/framework: versions : v7.25.0 beyondcode/laravel-websockets: versions : 1.6.0

The beyondcode/laravel-websockets version is the problem. Need to change that back to dev-master in the composer.json, then do a composer update and it works! No error!

I updated my instructions above and this seems to work now!

rennokki commented 4 years ago

You jumped from Laravel 5.7.x (which is not supported anymore) to 7.x by running composer update?

I see you're using 1.4^ which means that it also uses the latest 1.6.0, I'm not sure what is the problem anymore and it's confusing me.

A last, composer update with ^1.6 set for the package in composer.json is making this issue fixed?

fylzero commented 4 years ago

@rennokki This repo was written for Laravel v5.7. The fork/branch I've created has made all appropriate updates to get this to v7. Yes, running composer update bumps it to version 7 which is the intention of this fork/branch.

Yes, 1.4^ is resolving to 1.6.0. No, setting to ^1.6 will not / does not fix this. It needs to resolve to the dev-master version to work without an error.

Hope that helps clarify.

rennokki commented 4 years ago

I'm not sure what actually happens here as 1.6.0 stable is literally in the same point as master. https://github.com/beyondcode/laravel-websockets/compare/master...1.6.0

fylzero commented 4 years ago

This issue should be closed. It is a problem with the composer.json in my fork which I've just updated/fixed. Nothing to do with the core project.

Re-posting setup steps here:

I'm running Laravel Valet and using SQLite for my DB. Here are my setup steps...

git clone git@github.com:fylzero/laravel-websockets-demo.git cd laravel-websockets-demo git checkout update-to-laravel-7 cp .env.example .env touch database/database.sqlite Open .env file and set APP_URL=http://laravel-websockets-demo.test and DB_CONNECTION=sqlite then save Commented out DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD composer install composer update npm install npm audit fix php artisan key:generate php artisan migrate:fresh --seed php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config" php artisan websockets:serve Open http://laravel-websockets-demo.test and register a user Open http://laravel-websockets-demo.test/laravel-websockets in a new tab Select the app "Laravel Websockets" Click connect Type messages into the chat window @ http://laravel-websockets-demo.test/

Everything seems to be working, no errors in the console for either page for me.

fylzero commented 4 years ago

@rennokki I would do your own experiment and try both. All I can say is that it had dev-master when originally installed and worked correct without errors... then when running composer update it modified to 1.6.0 and broke... changing back to dev-master made it work correctly without error. ¯\_(ツ)_/¯

xlcrr commented 4 years ago

What is PUSHER_APP_PATH ?

anon-phantom commented 1 year ago

I was struggling with 500 Error till I figured it out

Error message: Attempt to read property "key" on null

  authEndpoint: `http://localhost:3060/laravel-websockets/auth`,
  auth: {
    headers: {
      'x-app-id': '**App ID**', // => my issue was HERE
      Authorization: 'Bearer  jwt TOKEN',
      'Access-Control-Allow-Origin': '*'
    }
  }

and I found it by looking into the file in vendor\beyondcode\laravel-websockets\src\Dashboard\Http\Controllers\AuthenticateDashboard.php

$app = App::findById($request->header('x-app-id'));

$broadcaster = new PusherBroadcaster(new Pusher(
  $app->key,
  $app->secret,
  $app->id,
  []
));

and changed the middlware in App\Providers\BroadcastServiceProvider.php

// from 
// Broadcast::routes();
// to
Broadcast::routes(['middleware' => ['auth:api']]);

another change in App\config\websockets.php

'middleware' => [
  'api', // => changed it from web to api
   Authorize::class,
],

enter image description here

hope this help :)