I'm developing a project with Laravel (back) and Vuejs (with Vuex). I also use Sanctum:auth to authenticate users, laravel-websockets and Laravel-Echo for broadcast.
Before, I had received an authentication problem on my console with the error: "POST 'broadcast / auth' 404 not found".
I was able to solve it after watching a tutorial that combined Sanctum, Vue and Laravel Echo in the same project.
However, now that I test the service, I realize that I can listen to public channels but not private channels.
From what I see on the websockets-dashboard, I don't even subscribe to private channels.
In my archive .vue:
import room from './Room'
import axios from 'axios'
import Echo from 'laravel-echo'
import Pusher from 'pusher-js'
console.log(Pusher);
...
export default {
...
data: () => ({
...
Echos:undefined
}),
mounted(){
...
this.instantiatingEcho();
},
methods:{
...
instantiatingEcho(){
axios({
method: "GET",
url: "http://127.0.0.1:8000/api/users",
headers: {
Authorization: `Bearer ${this.$store.state.user.token}`,
},
})
.then(({ data }) => {
console.log(data);
this.Echos = new Echo({
broadcaster: 'pusher',
key: process.env.VUE_APP_WEBSOCKETS_KEY,
wsHost: process.env.VUE_APP_WEBSOCKETS_SERVER,
wsPort: 6001,
forceTLS: false,
disableStats: true,
authorizer: (channel, options) => {
console.log(options);
return {
authorize: (socketId, callback) => {
axios({
method: "POST",
url: "http://127.0.0.1:8000/api/broadcasting/auth",
headers: {
Authorization: `Bearer ${this.$store.state.user.token}`,
},
data: {
socket_id: socketId,
channel_name: channel.name,
},
})
.then((response) => {
callback(false, response.data);
})
.catch((error) => {
callback(true, error);
})
},
}
}
})
})
this.enterinrom();
},
enterinrom(){
this.Echos.private('Room.2')
.listen('BroadcastRoom', (e) =>{
console.log(e)
});
},
}
}
channels.php:
Broadcast::channel('Room.{id}', function ($id){
return true;
});
Event:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
use App\Broadcasting\RoomChannel;
class BroadcastRoom implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $mensage;
public $id;
public function __construct($mensage, $id)
{
$this->mensage = $mensage;
$this->id = $id;
}
public function broadcastWith()
{
return ["mensage" => $this->mensage];
}
public function broadcastOn()
{
return new PrivateChannel('Room.'.$this->id);
}
}
api.php:
...
Broadcast::routes(['middleware' => ['auth:sanctum']]);
Route::middleware('auth:sanctum')->get('/users', function (Request $request) {
return $request->user();
});
Route::post('/users/login', function (Request $request) {
$user = User::where('email', $request->email)->first();
if (!$user || ($request->password != $user->password)) {
return response([
'message' => ['These credentials do not match our records.']
], 404);
}
$token = $user->createToken('idiot-online-token')->plainTextToken;
$response = [
'user' => $user,
'token' => $token
];
return response($response, 201);
});
web.php:
Route::get('/enviaevento/{id}', function ($id) {
return event(new \App\Events\BroadcastRoom('Uai só...', $id));
});
App\Providers\BroadcastServiceProvider::class in config/app.php is uncommented.
Results: enter image description here
Someone would can help me?
In the authorizer property please make sure that the response is correctly used. You could try to use response instead of response.data. I've been stuck on this problem for a while just to realize that the snippet in the documentation doesn't suffice my situation.