Laravel 9 presence channels for all users (guests and logged)

1.8k Views Asked by At

There are many similar topics, but no solution is correct.

I need to be able to "authenticate" logged in users and guests for a specific presence channel only. How can I achieve this?

The rest of the channels are to be available as standard only to logged in users.

2

There are 2 best solutions below

1
jpmc On

Came up with this the other day and it's just for a game so make up your own mind, but it looks okay to me. Maybe you can give me some security feedback ;D My situation is using token based auth with laravel sanctum.

If you want to use the presence channel, you need to have a user object for the guests too.

Broadcast::channel('{userRoom}', function ($user) {
    return ['id' => $user->id, 'name' => $user->name];
});

My solution was having a guest model and sql table in addition to the regular users table for fully authed users. In my case, both user and guest models have a room property, a string, the users can create a room, and guests can join that room.

Have a seperate end point for guest authentication. I gathered a name, device name, and room, because for a game it made sense, but the point is that it was passwordless. The route returns a guest object and a bearer token that the guest can use to 'authenticate' themselves.

In config/auth.php add the new model to user providers:

      'providers' => [
        'users' => [
           'driver' => 'eloquent',
           'model' => App\Models\User::class,
          ],
          'guests' => [
            'driver' => 'eloquent',
            'model' => App\Models\Guest::class,
          ]
       ],

Then just make sure your guests are supplying the bearer token when they set up their pusher instance. Javascript would be something like:

    var pusher = new Pusher('xxxxxxxxxxxxxx', {
      cluster: 'ap4',
      authEndpoint: "https://example.com/broadcasting/auth",
      auth: {
        headers: {
          Authorization: 'Bearer ' + token
        }
      }
    })

    var channel = pusher.subscribe('presence-xxxx');

    channel.bind("pusher:subscription_succeeded", function () {
      console.log("Subscription succeeded")
      console.log(channel.members.me)
      ...

I guess just make sure you aren't giving the guests access to stuff they aren't supposed to get into. It's basically like having user roles.

0
Hany Mohamed Sabry On

you need to know that private and presence channels are for authenticated and authorized users only.

if you want to broadcast for all you need to use public channel