msonowal
msonowal

Reputation: 1687

How to define or pass auth guard for broadcast authentication routes instead of default auth guard?

I am very new to realtime event broadcasting, I have simple laravel-echo-server setup and working with everything. I am unable to set/define authentication against other auth guard it is always checking with user/default guard defined in auth.php I have setup the authentication routes for each guards private channels in routes/channel.php as below per documentation.

For auth guard user private channels

Broadcast::channel('users.{id}', function ($user, $id) {
   Log::info(class_basename($user));
   return (int) $user->id === (int) $id;
});

For auth guard admin private channels

Broadcast::channel('admins.{id}', function ($admin, $id) {
   Log::info(class_basename($admin));
   return (int) $admin->id === (int) $id;
});

It works fine for guard user that is the first case but never worked for the second one i.e. admin guard. and the

Log::info(class_basename($admin)) always returns User class.

So, how do we pass or define that it should use admin guard instead of user. after exploring the inside of Illuminate\Broadcasting\Broadcasters\Broadcaster I found out that below in line 411

public function user($guard = null)
{
    return call_user_func($this->getUserResolver(), $guard);
}

So, if we can pass this guard parameter it can solve the purpose. If anyone can give me anything or way of authorising with multiple guard setup that will be very helpfull. Using Laravel 5.4, laravel-echo-server, Redis, Socket.IO

Upvotes: 5

Views: 3047

Answers (2)

Big Pete
Big Pete

Reputation: 146

I finally got this to work with 2 separate login screens and 2 separate users and customers tables.

Firstly I followed the Laracasts video on private channel broadcasting. The video says to put all the echo event listeners in your bootstrap.js. This will work with one users table. However for 2 separate tables users, customers you need to place the relevant echo event listeners in your 2 separate app.blade.php layouts files. For users in one and for customers in the other. However the listeners should be positioned at the bottom.

window.Echo.private('App.User.' +     window.Laravel.user.id) .listen('Event', e => { etc. });

window.Laravel = {!! json_encode([ 'customer' => auth()->guard('customer')->user() ]) !!};

window.Echo.private('App.Customer.' + window.Laravel.customer.id) .listen('Event', e => { etc. });

Then in your routes/channels.php

Broadcast::channel('App.User.{id}', function ($user, $id)
return (int) $user->id === (int) $id;
});

Broadcast::channel('App.Customer.{id}', function ($user, $id)
return (int) auth()->guard('customer')->user()->id === (int) $id;
}); // Note I do not compare "$user" here

Then in BroadcastServiceProvider.php

Broadcast::routes(['middleware' => 'web', 'auth:customer']);
require base_path('routes/channels.php');

//Remove Broadcast::routes();

A customer can receive a private message and so can a user. Hope this helps.

Upvotes: 1

user8392965
user8392965

Reputation:

Just like in the otherwhere, simply use Request facade in the closure.

In your case:

Broadcast::channel('admins.{id}', function ($user, int $id) {
   return Request::user('admin')->id === $id;
});

The arguments sent to the closure can not be change by user, it is controlled by laravel framework. (see BroadcastManage and RedisBroadcaster, or other implementations of Illumiante\Contracts\Broadcasting\Broadcaster)

Upvotes: 0

Related Questions