I finally found a way to do it: https://github.com/archtechx/tenancy/issues/845#issuecomment-1096788174
Tenancy aware broadcasting with authentication
HI, I am creating a simple restaurant management system API which fires a broadcasting event when a customer places an order from the mobile app and the restaurant will receive that event on a desktop client. I am using beyondcode/laravel-websockets for broadcasting. I am using stancl/tenancy in this project so that it can be used by multiple restaurants with their own users and data.
For simplicity and testing purpose, I am using a separate Vue project and Postman to test the broadcasting. It worked fine and the broadcast was successfully received by Vue while using public channel, but I couldn't make it work using private channel and authentication.
I am using sanctum for authentication, so I modified the BroadcastServiceProvider as below:
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes(['middleware' => ['auth:sanctum']]);
require base_path('routes/channels.php');
}
}
I created a channel route in routes/channels.php to handle the request and authentication:
Broadcast::channel('customer-order', function ($user) {
return $user->role == "admin" || $user->role == "staff";
});
Below is the defined broadcast channel on my OrderPlaced event
....
/**
* Get the channels the event should broadcast on.
*
* @return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('customer-order');
}
....
I am using simple Vue.js app to listen to broadcasts:
import Echo from "laravel-echo";
import Pusher from "pusher-js";
window.Pusher = Pusher;
const token = "1|OZdkQFNRDpUxHNnXD7MFAyqlVo9dMCesA2ZkIDRz"
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'laravel_socket',
wsHost: '127.0.0.1',
authEndpoint: 'http://localhost/my-app/public/broadcasting/auth',
encrypted: true,
forceTLS: false,
wsPort: 6001,
wssPort: 6001,
disableStats: true,
enabledTransports: ['ws', 'wss'],
auth : {
headers : {
Authorization: "Bearer " + token,
Accept: "application/json",
}
},
})
window.Echo.private('customer-order')
.listen('OrderPlaced', (e) => {
console.log(e)
})
With this configuration, Vue.js app cannot connect to the socket server because server responds with POST http://localhost/my-app/public/broadcasting/auth 401 (Unauthorized)
Again, everything works if I use public channels for broadcasting and listening without any reference to tenancy and authentication. My main concern is how do I set up tenancy aware broadcasting with authentication?
Please or to participate in this conversation.