kakajansh / echo

Laravel Echo for your Flutter apps.
MIT License
107 stars 68 forks source link

Connect private channel with Laravel backend, Pusher and Echo #29

Closed msassa closed 2 years ago

msassa commented 3 years ago

I don't know, or I can't figure out how to get authorized for subscribe to a private channel

If I put this code:

PusherOptions options = PusherOptions(
      cluster: 'us2',
      auth: PusherAuth(
        _apiService.domain + '/broadcasting/auth',
        headers: {
          'Authorization': 'Bearer ' + _apiService.getToken().toString(),
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
      ),
    );

I got an error about "CSRF token mismatch."

If I use another endpoint, I don't know how to make the auth and return the {auth:{key:value}}

Can you please, provide a complete example on how to achieve this?

Public channels just work fine ...

thedark1233 commented 3 years ago

First of all, thanks for this great plugin !

I also can't figure out how to get authorized for a private channel, It would be great if you can share the full demo =)

I've tried your setup @msassa and tried with a prefix for the authEndPoint : '/api/broadcasting/auth

I'm using Laravel Websockets + Passport + Flutter + Laravel Echo

I added this to the BroadcastServiceProvider in Laravel

 Broadcast::routes([
            'prefix' => 'api',
            'middleware' => 'auth:api'
        ]);

This is my PusherOptions in Flutter

 PusherOptions options = PusherOptions(
host: myHost,
      port: 6001,
      encrypted: false,
      auth: PusherAuth(
       myHost + '/api/broadcasting/auth',
       headers: {
          'Authorization':  'Bearer ' + bearerCode,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
      ),
    );

And here the Echo instance :


  echo = new Echo({
      'broadcaster': 'pusher',
      'client': pusherClient,
      'authEndpoint': myHost + '/api/broadcasting/auth',
      'auth': {
        'headers': {
          'Authorization':  'Bearer ' + bearerCode,
          'Accept': 'application/json'
        }
      }

//where pusherClient is an Instance of FlutterPusher with the PusherOptions above

It works like a charm for public channels, but nothing happens when trying with a private channel, When the channel is public it's listenning to the event

I tried from a web app with Vuejs it works for both public and private ( private as I can see the auth connexion in the WS dashboard ), so the websocket isn't the problem, I use the same Bearer for the same user for Flutter example app butnothing happens not even asking the WS for an auth key like it does with Vuejs

If anyone can help I'm stuck since few days and had no more hair to pull out x)

thedark1233 commented 3 years ago

It's working from my side, after some debugging I, First, Had to add in the AndroidManifest the internet permission and android:usesCleartextTraffic to true ( maybe a noob move but I'm new to Flutter )

    <uses-permission android:name="android.permission.INTERNET" />

    <application
         ...
        android:usesCleartextTraffic="true"
        ...
   />

Second, I found that the problem was also coming from my backend ( Laravel )

try adding this in the getPusherClient() function to debug what's going


 return FlutterPusher('websocketkey', options, lazyConnect: true, enableLogging: true,
      onConnectionStateChange: (ConnectionStateChange events) =>
          log("${events.currentState}"),
      onError: (ConnectionError e) =>
          log("Error occurred logging you in with auth tokens ${e.toJson()}"),);

For me the authEndPoint was always returning a 403 error so I had to debug in my Laravel App, I found that no user were recognized.

So I had to add my customAuthServiceProvider following this Medium article ( chapter 4 - (8) ) Thanks to him, it worked like a charm.

heywhy commented 3 years ago

I don't know, or I can't figure out how to get authorized for subscribe to a private channel

If I put this code:

PusherOptions options = PusherOptions(
      cluster: 'us2',
      auth: PusherAuth(
        _apiService.domain + '/broadcasting/auth',
        headers: {
          'Authorization': 'Bearer ' + _apiService.getToken().toString(),
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
      ),
    );

I got an error about "CSRF token mismatch."

If I use another endpoint, I don't know how to make the auth and return the {auth:{key:value}}

Can you please, provide a complete example on how to achieve this?

Public channels just work fine ...

The issue you are having is a result of enabling CSRF middleware which is attached to the web route group. I'll suggest you move the broadcast authentication route to the API route group which doesn't require passing the _csrfToken field.

chinloyal commented 3 years ago

@thedark1233 Try this pusher client (https://pub.dev/packages/pusher_client) subscribing to laravel private channels works, and it also supports private encrypted channels and triggering events

mosaw commented 2 years ago

did any one used it with paid host I used a digital ocean vps with nginx and it dosenot work @chinloyal