Laravel Echo + Laravel Passport auth in private / presence websockets channels - laravel

I'm trying to connect to a presence wesocket channel using Laravel Echo. I'm also using Laravel Passport. I followed lots of tutorials, but I'm getting 403 error codes, 302 codes and so on. I'm hosting my websocket server locally, using laravel-websockets library to handle connections. Vue is my front-end library.
This is what I tried:
Edit the BroadcastServiceProvider's boot function.
public function boot() {
Broadcast::routes(["prefix" => "api", "middleware" => "auth:api"]);
require base_path('routes/channels.php');
}
Add the Authorization token to Echo headers and add an authEndpoint property in bootstrap.js
window.Echo = new Echo({
broadcaster: 'pusher',
authEndpoint: '/broadcasting/auth',
key: process.env.MIX_PUSHER_APP_KEY,
auth:{
headers:{
'Authorization': 'Bearer ' + auth_token,
}
},
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
//encrypted: false
wsHost: window.location.hostname,
wsPort: 6001});
Try joining the channel from Vue.
mounted(){
Echo.join(`game.0`)
.here((users) => {
alert("In the channel!");
})
.joining((user) => {
console.log("Someone entered");
})
.leaving((user) => {
console.log(user.name);
})
.listen('GameEvent', (e) => {
console.log("Hey")
});}
routes/channels.php file:
Route::prefix('/user')->group(function(){
Route::post('/login','api\v1\LoginController#Login');
Route::middleware('auth:api')->get('/all','api\v1\user\UserController#index');});
The event file:
class GameEvent implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $gameEvent;
public $gameId;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($gameEvent,$gameId)
{
//
$this->gameEvent = $gameEvent;
$this->gameId = $gameId;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
//return new PrivateChannel('channel-name');
return new PresenceChannel('game.0');
}
public function broadcastWith(){
return $this->gameEvent;
}
}
At this point, if I try to connect to the channel, the broadcasting/auth request gets a 302 code (Found). I found an answer in another post that claimed to solve this by adding this to the routes/web.php file.
Route::post('/broadcasting/auth', function(Request $request){
$pusher = new Pusher\Pusher(
env('PUSHER_APP_KEY'),
env('PUSHER_APP_SECRET'),
env('PUSHER_APP_ID'),
array(
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http',
)
);
IT WORKED, the broadcasting/auth request gives a 200 code, and I get this as a response:
{"auth":"ABCFEDG:0bfff7db6506158755b012a47873799849d4e6b331f68da4bedd1caea04ad657"}
but the here, joining, leaving functions are not triggering.
Echo.join('game.0')
.here((users) => {
alert("In the channel!");
})
What should I do to get this to work?
Screenshot of the network inspector:

Did you add auth route in channel.php ?
please check it
You should make it based on channel name
Route::channel('game.'.$id,function($user,$id){
return .....
})

no channels there . Did you miss Broadcast::channel ?

try to change your authEndpoint like this
authEndpoint: window.location.hostname+'/api/broadcasting/auth',
and don't forget to update your BroadcastServiceProvider
Broadcast::routes([
'prefix' => 'api',
'middleware' => 'auth:api'
]);
require base_path('routes/channels.php');

Related

Laravel websocket private channel with pusher broadcast/auth return 403 error

I tried to use laravel websocket with ionic; i used laravel-echo-ionic on my ionic project
in BroadcastServiceProvider.php i commented the Broadcast::routes() and added it to routes/api.php
Broadcast::routes(['middleware' => ['auth:api']]);
I used another model Customers for my auth:api and use laravel passport.
in my channel.php
Broadcast::channel('App.Models.Customers.{id}', function ($customers, $id) {
return Auth::id() === $id; // i tried $customers->id to
}, ['guards' => ['api']]);
and in my ionic service provider i have
this.echo = new Echo({
broadcaster: 'pusher',
key: 'key', // .env
wsHost: 'localhost',
wsPort: 6001,
cluster: 'eu',
forceTLS: false,
disableStats: true,
authEndpoint: 'http://localhost/api/broadcasting/auth',
auth: {
headers: {
Authorization: 'Bearer ' + res.token
}
}
});
this.echo.private('App.Models.Customers.'+this.user_id).listen('.test', (data) => {
console.log(data)
})
when using public channel it work well, but when using private channel, the http://localhost/api/broadcasting/auth request return error 403
I don't know if it's the proper way to do it with auth:api but i move my Broadcast::channel that used auth:api guard to my routes/api.php, so there i can access to my broadcast/auth within api middleware

Laravel Echo connects but is not Subscribing to Pusher Private Channel on prod server

I have a Laravel API backend using Sanctum for auth. I'm using VueJS as the frontend with Laravel Echo to listen for broadcasted events on private channels. On my local development machine I can connect to and subscribe to a Private channel without issue. I can see this in the Pusher Debug Console.
However, on my prod server I can see that the connection is made to Pusher in the Debug Console but the subscription isn't made. I have no idea why this is... Here is my config files below:
config/broadcasting.php
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => 'eu',
// 'useTLS' => true
],
routes/channels.php - I return true to make sure it isn't the auth causing it
Broadcast::channel('calendar.{id}', function ($user, $id) {
return true;
});
I have uncommented the App\Providers\BroadcastServiceProvider::class, in config/app.php and added the Broadcast::route function to use sanctum.
public function boot()
{
Broadcast::routes(['middleware' => ['auth:sanctum']]);
require base_path('routes/channels.php');
}
My frontend config in main.js (baseURL is the URL of our API, ex: https://site.oursite.com:
window.Pusher = require("pusher-js");
window.Echo = new Echo({
broadcaster: "pusher",
key: "my key",
cluster: "eu",
encrypted: true,
authEndpoint: config.get("baseUrl") + "/broadcasting/auth",
auth: {
headers: {
authorization: `Bearer ${token.getToken(1)}`,
},
},
});
axios.defaults.withCredentials = true;
axios.defaults.baseURL = config.get("baseUrl");
axios.get("/sanctum/csrf-cookie");
let socketId = false;
window.Echo.connector.pusher.connection.bind("connected", function() {
socketId = window.Echo.socketId();
});
//set the socket ID on each axios request
axios.interceptors.request.use((conf) => {
// pusher socket
if (socketId) conf.headers["X-Socket-ID"] = socketId;
// add auth token
conf.baseURL = config.get("baseUrl") + "/api/";
if (token.hasToken(1))
conf.headers.authorization = `Bearer ${token.getToken(1)}`;
return conf;
});
And the listeners:
window.Echo.private(`calendar.${calendarId}`).listen(
".entry.created",
(payload) => {
console.log(payload);
}
);
Is there anything specific that needs to be set up on production vs local development?
The only thing I can think that is different in the environments is that the prod server uses SSL whereas on local dev I do no.
I'll appreciate it if someone has any ideas that I can try.

Laravel broadcast doesnt get triggered

Trying to send user list to specific users after a friend requests been made.using pusher,vuejs 2.6,laravel 5.7 but in my function the broadcast its not getting triggered
when i do dd in channel it works! also in the construct function. so im kind of confused whether the broadcast itself gets called but I dont see a second XHR request for the list or some other situation !!?
//Boostrap.js
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
app_id: '7xxxx4',
key: 'xxxxxxxxxxxxxxxxxxx',
secret: 'xxxxxxxxxxxxxxxxxxx',
encrypted: false
});
//Vuejs component
mounted(){ window.Echo.channel("newReq").listen(".newreq-list", e => {
this.getrequestedList();
});
.env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=7xxxxx4
PUSHER_APP_KEY=xxxxxxxxxxxxxxxxxxx
PUSHER_APP_SECRET=xxxxxxxxxxxxxxxxxxx
PUSHER_APP_CLUSTER=ap2
Broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => false,
],
],
channels.php
Broadcast::channel('newReq', function(){
return true;
});
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
class Friendreq implements ShouldBroadcastNow
{
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public $req;
public function __construct($req)
{
$this->req = $req;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('newReq');
}
public function broadcastAs()
{
return 'newreq-list';
}
}
//in friendscontroller.php
broadcast(new \App\Events\Friendreq($requestToadd));
I have also uncommented App\Providers\BroadcastServiceProvider
for the result it should call the function this.getrequestedList(); which is a working function cause its also called in created()
Thanks for any help
2 days of debugging,searching was very simple :
PUSHER_APP_CLUSTER=ap2
the above line has to be CHANGED to this
PUSHER_APP_CLUSTER=eu
and now it gets triggered and working the way i want

Pusher Eloquent Event trigger returns false HTTP API Req Laravel 5.7

I have two eloquent model events performed by an API (insert and update). I have tested these with Postman and they're working I am getting logs of the operations performed. I have removed the logs, since my goal is to trigger pusher events when one of these events are triggered. I have set up pusher installing it from the composer. I have updated the config files and env ,which I will show below, and I have made some triggers to the channel from the pusher dashboard.
I am using Ubuntu 18.04 with apache, laravel 5.7 and when attempting an HTTP request I noticed that $re = $pusher->trigger('api-channel', 'model.insert', array('message' => 'hello')); returns false. I have tried both commenting the encrypt line in the config and setting it to the false, updating the time via ntp as suggested on other posts but these don't resolve my issue. I have tried triggering the event both from the controller and from the eventserviceprovider boot function but the result is always the same.
This is my js
//event listener for document repo api
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
var pusher = new Pusher('*****', {
cluster: 'eu',
forceTLS: true
});
var channel = pusher.subscribe('api-channel');
channel.bind('model.insert', function(document) {
alert(JSON.stringify(document.message));
console.log(document);
});
I have tested if the config are setup correctly by adding these lines of code in the BroadCastManager.php
var_dump($config['key']);
var_dump($config['secret']);
var_dump( $config['app_id']);
var_dump($config['options']);
exit;
And from the output I can tell that they are correct.
This is my code when attempting trigger from the controller
namespace App\Http\Controllers;
.
.
.
use Illuminate\Http\Request;
use Pusher\Pusher as Pusher;
.
.
.
if ($model->save()) {
$options = array(
'cluster' => 'eu',
'encrypted' => false
// 'host' => '127.0.0.1',
// 'port' => 6001,
// 'scheme' => 'http'
);
$pusher = new Pusher(
'key',
'secret',
'app-id',
$options
);
// dd($pusher->get_channels());
$re = $pusher->trigger('api-channel', 'model.insert', array('message' => 'hello'));
dd($re);
return new ModelResource($model);
}
I have also attempted creating a laravel event and listener and triggering that event in the controller after a model change has been performed. In that case I get this error:
"message": "",
"exception": "Illuminate\\Broadcasting\\BroadcastException",
"file": "/home/usr/projects/tdv/vendor/laravel/framework/src/Illuminate/Broadcasting/Broadcasters/PusherBroadcaster.php",
"line": 117,
"trace": [
{
"file": "/home/usr/projects/tdv/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastEvent.php",
"line": 48,
"function": "broadcast",
"class": "Illuminate\\Broadcasting\\Broadcasters\\PusherBroadcaster",
"type": "->"
This is my event class. It is registered in the event service provider.
namespace App\Events;
use App\ModelRepository;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Log;
class ModelEvent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $modelRepository;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(ModelRepository $modelRepository)
{
//
$this->$modelRepository = $modelRepository;
$this->broadcast();
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('api-channel');
}
public function broadcast()
{
$options = array(
'cluster' => 'eu',
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http',
'useTLS' => true
);
$pusher = new Pusher(
'***',
'***',
'***',
$options
);
return $pusher->trigger('api-channel', 'model.insert', array('data' => $this->modelRepository));
}
}
and in this case this is how I trigger the event in the controller
event(new ModelEvent(new ModelRepository()));
Thanks in advance! :)

Pusher and Laravel 5.3 Event Broadcasting

Trying to use Laravel 5.3 with pusher, but it seems its not working correct in my code.
My .env is correct
PUSHER_APP_ID= myappid
PUSHER_KEY= mykey
PUSHER_SECRET= mysecret
This is my 'pusher' configurations in broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_KEY'),
'secret' => env('PUSHER_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => 'eu',
'encrypted' => true,
],
],
I created an event, here it is
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ProposalEvent implements ShouldBroadcast
{
use InteractsWithSockets, SerializesModels;
public $data;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the channels the event should broadcast on.
*
* #return Channel|array
*/
public function broadcastOn()
{
return ['test-channel'];
// return new PrivateChannel('test-channel');
// return new PresenceChannel('test-channel');
}
}
my javascript
Pusher.logToConsole = true;
var pusher = new Pusher("mykey", {
cluster: 'eu',
encrypted: true
});
var channel = pusher.subscribe('test-channel');
channel.bind('App\\Events\\ProposalEvent', function(data) {
alert(data);
});
and finally in my view
event(new App\Events\ProposalEvent('some data'));
unfortunately this is not working for me, but when i use pusher->trigger like this, without event, it working fine, and i see message in pusher debug console
$options = array(
'cluster' => 'eu',
'encrypted' => true
);
$pusher = new Pusher(
'mykey',
'mysecret',
'myid',
$options
);
$data['message'] = 'some data';
$pusher->trigger('test-channel', 'my-event', $data);
I have searched for solution in Laravel documentation and other resources. There are questions with same problem in stackoverflow, but there are no response.I will be grateful if somebody can help me, because i can't find solution for several days
I was stuck in the same situation and found out that I wasn't using the queue!
In the documentation it says
Before broadcasting events, you will also need to configure and run a queue listener. All event broadcasting is done via queued jobs so that the response time of your application is not seriously affected.
I deleted the config/queue.php file before since I thought I wasn't using it. Maybe you're doing the same thing as me or having some problem with the queue.
Try to pass pusher credentials directly through config/broadcasting.php
It worked for me.
'default' => 'pusher',
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => '***',
'secret' => '**',
'app_id' => '**',
'options' => [
],
],
],
enter code here
triggering event in the views is a mistake when a page is loaded the php is execute first then js is loaded wich mean that you fired event with php before js listner wich will displaye an error this can the first case
the second case is that you didn't downloaded https://curl.haxx.se/docs/caextract.html
if you did go to php.ini and in [curl]you will find somthing like curl-info unecomment it
and right the path to culr file

Resources