iamsubingyawali's avatar

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?

0 likes
1 reply

Please or to participate in this conversation.