Laravel echo admin channel authentication error - laravel

I'am using Laravel 5.5 with echo for an admin panel ,
the main guard (web) is related to Admin class ,
the private channel name that i want to get is Admin.1 ,
The problem is when i change the channel name from
Echo.private('App.User.' + this.userid)
to
Echo.private('App.Admin.' + this.userid)
it gets me this error
broadcasting/auth 500 (Internal Server Error)
what i tried is :
i put this
Broadcast::routes(['middleware' => [ 'api', 'web','auth' ] ]);
in web.php and api.php and BroadcastServiceProvider.php put it doesn't seem to work
i also tried this soltion
How to define or pass auth guard for broadcast authentication routes instead of default auth guard?

In your echo settings set authEndpoint to 'broadcasting/auth'.
here's the code that works for me after facing the same problem.
new Echo({
broadcaster: 'pusher',
key: '{{env("PUSHER_APP_KEY")}}',
cluster: 'us2',
encrypted: true,
authEndpoint: '{!! env("APP_URL") !!}/broadcasting/auth',
});

I solve my problem by :
adding this to BroadcastServiceProvider
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
/*
* for auth user channel
*/
Broadcast::channel('App.Admin.{id}',function($user, $id){
return (int) $user->id === (int) $id;
});
}

Related

Getting local.ERROR: Route [login] not defined when uploading file from ionic to laravel using fileTransfer plugin

I'am using Rest api to upload file from ionic to laravel , First i prepare the api in laravel and the function in controller it work's fine in laravel , second in ionic app i'am using file , filepath , filetransfert as you see in the code bellow . but when i test i get local.ERROR: Route [login] not defined
in laravel.log.
this my code in laravel controller
public function complaintsfile(Request $request){
$reclamation = Reclamation::latest('updated_at')->first();
$file = new Filee;
if(!$request->hasFile('file')){
return response()->json([
"action"=>"File empty"
]);
}
else{
$this->validate($request,[
'file' => 'required|mimes:doc,png,jpg,docx,txt,pdf|max:2048'
]);
$extention = time().'.'.$request->file->getClientOriginalExtension();
$fileName ="complain".'.'.$extention;
$request->file->move(public_path('upload'), $fileName);
$file->file= $fileName;
$file->rec_id=$reclamation->id;
$file->save();
}
}
Also this my code in ionic
export class FillPage {
myRec = {
type:'' ,
project:'' ,
description:'',
}
myFile={
file:''
}
mood:any;
project:any;
uploadText:any;
downloadText:any;
fileTransfer:FileTransferObject;
constructor(public navCtrl: NavController, public navParams: NavParams,public complaint: ComplaintProvider
,public transfer:FileTransfer,public file:File,public filePath:FilePath,public fileChooser:FileChooser) {
this.complaint.Type().then((data)=>{
// console.log(JSON.stringify(data))
this.mood=data["type"];
})
this.complaint.Project().then((data)=>{
// console.log(JSON.stringify(data))
this.project=data["projects"];
})
this.uploadText="";
this.downloadText="";
}
uploadFile(){
this.fileChooser.open().then((uri)=>{
this.filePath.resolveNativePath(uri).then((nativepath)=>{
this.fileTransfer =this.transfer.create();
let options:FileUploadOptions={
fileKey:"pdf",
fileName:"file.pdf",
chunkedMode:false,
headers:{},
mimeType:'pdf'
}
this.uploadText ="uploading .....";
this.fileTransfer.upload(nativepath,'http://192.168.1.14:8000/api/complainfile',options).then((data)=>{
alert("transfer done="+JSON.stringify(data));
this.uploadText="";
},(err)=>{
this.uploadText=""
})
},(err)=>{
alert(JSON.stringify(err))
})
},(err)=>{
alert(JSON.stringify(err));
})
}
AbortUplaod(){
this.fileTransfer.abort();
alert("upload cancel.");
}
api.php
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::group([
// 'middleware' => 'api',
// 'namespace' => 'App\Http\Controllers',
'prefix' => 'auth'
], function ($router) {
Route::post('login', 'API\AuthenController#login');
Route::post('logout', 'API\AuthenController#logout');
Route::post('refresh', 'AuthenController#refresh');
Route::post('me', 'AuthenController#me');
Route::get('/me','API\AuthenController#me');
});
Route::get('/notif','API\ProjetController#notifications');
Route::get('/notification','API\ProjetController#notif');
Route::get('/me','API\AuthenController#guard');
Route::post('/login','API\AuthenController#login');
Route::post('/userauth','API\AuthenController#userauth');
Route::post('/markAsRead','API\ProjetController#MarkUnread') ;
Route::apiResource('client' ,'API\UserController#dashbord');
Route::get('membrep','API\UserController#Membreprojet');
Route::get('/chef', 'API\UserController#chef');
Route::post('/ajouterChefDeProjet','API\UserController#ajouterChefDeProjet');
Route::post('user-login' ,'API\UserController#login');
Route::apiResource('membre','API\UserController');
Route::post('updateuserconnecte','API\UserController#updateuserconnecté');
Route::get('/chef','API\UserController#chefprojet');
Route::get('/chefwP','API\UserController#chefprojetwP');
Route::get('userprofile/{id}','API\UserController#userprofile');
//UserProjet
Route::apiResource('/userprojet' ,'API\UserProjetController');
Route::get('/membreid/{id}','API\UserProjetController#show');
Route::get('/projetsuser','API\UserProjetController#projetuser');
Route::post('/chefdeprojet','API\UserProjetController#storeChef');
Route::post('/chefdeprojetparchef','API\UserProjetController#storeChefparchef');
//Client
//Route::post('/api/clientpname','API\UserController#updatename');
Route::get('nameprojet' ,'API\UserController#nomdeprojet');
Route::get('clientp','API\UserController#clientprojet');
Route::post('/ajouterClient','API\UserController#ajouterClient');
Route::get('/afficheclient', 'API\UserController#client');
//Projet
Route::get('/getProjects', 'API\ProjetController#getProjects');
Route::apiResource('projet' ,'API\ProjetController');
Route::post('/role' ,'API\ProjetController#role');
Route::get('/role','API\ProjetController#getrole');
Route::get('/projetadmin','API\ProjetController#adminp');
Route::get('/getProjectsUserConnecte', 'API\ProjetController#getProjectsUserConnecte');
//Commentaire
Route::post('/comments/{key}', 'API\CommentController#store');
Route::get('/comments', 'API\CommentController#show');
Route::post('/commentsreponse/{key}', 'API\CommentController#storereply');
Route::post('/commentsreponset/{key}', 'API\CommentController#storereplyt');
Route::get('/commentreply', 'API\CommentController#showreply');
Route::post('/commentst/{key}', 'API\CommentController#storet');
Route::get('/commentst', 'API\CommentController#showt');
//calendar
Route::apiResource('/calendar', 'API\CalenderController');
//gantt
Route::resource('/task', 'API\TaskController');
Route::post('/task/{key}','API\TaskController#store');
Route::put('task/{id}','API\TaskController#update');
Route::delete('task/{id}','API\TaskController#destroy');
Route::post('link','API\LinkController#store');
Route::put('link/{id}','API\LinkController#update');
Route::delete('link/{id}','API\LinkController#destroy');
//Route::re}source('link', 'API\LinkController');
Route::get('/tasks','API\TaskController#getTask');
Route::get('/tasksdetail','API\TaskController#getTaskt');
//Task
Route::post('/taskassign/{id}/{membre}','API\TaskController#assign');
Route::get('/userTask','API\TaskController#user');
Route::get('/hasparent','API\TaskController#hasparent');
Route::get('membret/{id}','API\UserProjetController#showt');
Route::get('warn','API\TaskController#warning');
Route::get('membretask','API\TaskController#showmembre');
//reclamation
Route::resource('reclamation','API\ReclamationController');
Route::get('/complain','API\ReclamationController#complaints');
Route::post('/complainfile','API\ReclamationController#complaintsfile');
Route::post('/complainfileionic','API\ReclamationController#complaintsfileionic');
Route::get('/filesComplain/{id}','API\FileController#complaintsfile');
Route::get('/projetRec','API\ReclamationController#projets');
Route::post('/reclamationassign/{id}/{membre}','API\ReclamationController#assign');
Route::post('/type' ,'API\ReclamationController#type');
Route::get('/type','API\ReclamationController#gettype');
Route::post('/reclamationTerm/{id}','API\ReclamationController#terminerReclamation');
Route::post('/reclamationAlert/{id}','API\ReclamationController#alertReclamation');
Route::get('/reclamationmobile','API\ReclamationController#reclamationmobile');
//profil
Route::put('profile', 'API\UserController#updateProfile');
Route::get('membrechef','API\UserController#Membrechefprojet');
//File
Route::get('/file/{id}','API\FileController#files');
Route::post('formSubmit/{id}','API\FileController#formSubmit');
Route::get('/filet/{id}','API\FileController#filest');
Route::post('formSubmitt/{id}','API\FileController#formSubmitt');
Route::post('formSubmitR','API\FileController#formSubmitR');
//stata
Route::get('/Nprojects','API\StatController#Nprojects');
Route::get('/Nclients','API\StatController#Nclients');
Route::get('/Nusers','API\StatController#Nusers');
Route::get('/Nleaders','API\StatController#Nleaders');
Route::get('/stats','API\StatController#stats');
Route::get('/Uprojects','API\StatController#Uprojects');
Route::get('/Ustats','API\StatController#Ustats');
Route::get('/Utasks','API\StatController#Utasks');
Route::get('/Cprojets','API\StatController#Cprojets');
Route::get('/Cprojet','API\StatController#projetsclient');
Route::get('/Ucomplaint','API\StatController#complaints');
Route::get('/Nprojectsc','API\StatController#NprojectsC');
Route::get('/NcomplaintsC','API\StatController#NcomplaintsC');
//});
Route::get('/data/{id}', 'API\GanttController#get');
Route::get('/data', 'GanttController#get');
Route::get('/verifcomplaint' ,'API\ReclamationController#verifcomplaint');
Anyone know this problem please !
I guess this is probably because you are not authorized
you need to add to header request in iconic the Bearer {token}
and add
Accept: application/json

Laravel broadcast not alerting the message on the frontend

I am quite new to this laravel event so I am quite unable to get it done correctly.
I am trying to fire an event to notify the user when the job is completed. So, I am triggering an event at the end of the job as
event(new AmenityUploaded($this->data['property_id']));
My event looks like:
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;
class AmenityUploaded implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $property_id;
public function __construct($property_id)
{
$this->property_id = $property_id;
}
public function broadcastOn()
{
return new PrivateChannel('channel.amenity.'.$this->property_id);
}
public function broadcastAs()
{
return 'amenity-uploaded';
}
}
And in routes/channel.php
Broadcast::channel('channel.amenity.{propertyId}', function ($user, $propertyId) {
// return $user->id === \App\Models\Property::find($propertyId)->updated_by;
return true;
}
And in view, I am using javascript as:
view
<script>
Pusher.logToConsole = true;
var pusher = new Pusher('xxxxxxxxxxxxxxxxxxxxx', {
cluster: 'us3',
forceTLS: true
});
$id = '<?php echo $r->id; ?>';
var channel = pusher.subscribe(`channel.amenity.${$id}`);
channel.bind('amenity-uploaded', function(data) {
alert(JSON.stringify(data));
});
</script>
And my .env looks like:
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=xxxxx
PUSHER_APP_KEY=xxxxxxxxxxxxxxxxxxxx
PUSHER_APP_SECRET=xxxxxxxxxxxxxxxxxxxx
PUSHER_APP_CLUSTER=us3
So, whenever I run the queue with php artisan queue:work --tries=3. In the end, I could see that App\Events\AmenityUploaded being fired. However, I could not see any alert on the front end.
However, If I try to push notifications from the pusher dashboard, it alerts successfully on the app successfully. While pushing from pusher debug console, I use the channel as channel.amenity.1 and event as amenity-uploaded
##Update
I have added a block in event as broadcastWith:
public function broadcastWith()
{
// This must always be an array. Since it will be parsed with json_encode()
return [
'name' => 'Saroj',
'message' => 'Message',
];
}
And, this is successfully showing in pusher dashboard. However, not alerting in the frontend yet.
update 2
Tried with echo: Added following code in bootstrap.js
import Echo from 'laravel-echo'
import Pusher from "pusher-js"
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'xxxxxxxxxxxxxxxxxxxx',
cluster: 'us3',
encrypted: true
});
And in view:
<script>
$id = '<?php echo $r->id; ?>';
Echo.channel(`channel.amenity.${$id}`)
.listen('.amenity-uploaded', (data) => {
alert(JSON.stringify(data));
});
</script>
Still the same, if fired from the pusher dashboard, an alert will be shown in frontend. After finishing jobs, the event can be seen at the pusher dashboard, however not on the frontend.
I think the issue is that you use only Pusher at frontend without laravel-echo which should be required to work with private channels. Pusher itself doesn't know that it must authorise, laravel-echo does that out of the box.
This is how I init Pusher and Echo:
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: fromPHP.PUSHER_APP_KEY,
cluster: fromPHP.PUSHER_CLUSTER,
encrypted: true
});
and this is how I listen for private events:
Echo.private(channel).listen('.amenity-uploaded', data => alert(JSON.stringify(data)));
Notice the leading . before amenity-uploaded. That's required when you customise broadcastAs (https://laravel.com/docs/5.8/broadcasting#broadcast-name)

Private Channel not working in Laravel

In my ChatEvent i called function
public function broadcastOn()
{
return new Channel('chat');
}
And in app.js i have Echo.
Echo.channel('chat')
.listen('ChatEvent', (e) => {
this.chat.message.push(e.message);
console.log(e);
})
It works pretty well. But, when i change Channel to PrivateChannel in function broadcastOn() and in app.js I change
Echo.private('chat')
.listen('ChatEvent', (e) => {
this.chat.message.push(e.message);
console.log(e);
})
I have error POST broadcasting/auth 403 (Forbidden) ## And
Can I use Channel instead of PrivateChannel?
Like mentioned in document you have to define the authorization rule for this private channel
https://laravel.com/docs/5.5/broadcasting#authorizing-channels
edit your routes/channels.php file
Broadcast::channel('chat', function ($user) {
return true; //for public access
// or
return $user->can('chat'); //using gate
});
else use the channel for public access
When you use Private or PresenceChannel, Fix Error 403 /broadcasting/auth with Laravel version > 5.3 & Pusher, you need change your code in resources/assets/js/bootstrap.js with
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'your key',
cluster: 'your cluster',
encrypted: true,
auth: {
headers: {
Authorization: 'Bearer ' + YourTokenLogin
},
},
});
And in app/Providers/BroadcastServiceProvider.php change by
Broadcast::routes()
with
Broadcast::routes(['middleware' => ['auth:api']]);
or
Broadcast::routes(['middleware' => ['jwt.auth']]); //if you use JWT
it worked for me, and hope it help you.
Try this
in Chat event add
public function broadcastAs()
{
return 'new.chat';
}
in your javascript file
Echo.channel('chat')
.listen('.new.chat', (e) => {
console.log(e);
})
if use api
window.Echo.connector.options.auth.headers['Authorization'] = `Bearer ${user.api_token}`;
if use session auth without top code

POST http://localhost:8000/broadcasting/auth 403 (Forbidden)

I am trying to make my app connecting to pusher on a private channel.
But I am getting the following error in console:
POST http://localhost:8000/broadcasting/auth 403 (Forbidden)
app.js
/**
* First we will load all of this project's JavaScript dependencies which
* includes Vue and other libraries. It is a great starting point when
* building robust, powerful web applications using Vue and Laravel.
*/
require('./bootstrap');
window.Vue = require('vue');
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
Vue.component('payment', require('./components/Payment.vue'));
Vue.component('form-ajax', require('./components/FormAjax.vue'));
Vue.component(
'passport-clients',
require('./components/passport/Clients.vue')
);
Vue.component(
'passport-authorized-clients',
require('./components/passport/AuthorizedClients.vue')
);
Vue.component(
'passport-personal-access-tokens',
require('./components/passport/PersonalAccessTokens.vue')
);
const app = new Vue({
el: '#app'
});
Echo.private(`articles.admin`)
.listen('ArticleEvent', function(e) {
console.log(e);
});
Error
What maybe the cause of the error and how to resolve it.
Error 403 /broadcasting/auth with Laravel version > 5.3 & Pusher, you need change your code in resources/assets/js/bootstrap.js with
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'your key',
cluster: 'your cluster',
encrypted: true,
auth: {
headers: {
Authorization: 'Bearer ' + YourTokenLogin
},
},
});
And in app/Providers/BroadcastServiceProvider.php change by
Broadcast::routes()
with
Broadcast::routes(['middleware' => ['auth:api']]);
or
Broadcast::routes(['middleware' => ['jwt.auth']]); //if you use JWT
it worked for me, and hope it help you.
Have you tried to customise your authEndpoint.
this thing works on my end.
bootsrap.js
window.Echo = new Echo({
broadcaster: 'pusher',
// ...
authEndpoint: '/custom/endpoint/auth'
});
In my case I have used a custom auth guard which is causing the problem.
I have added the middleware to pass my custom auth guard and this solves the problem.
public function boot()
{
Broadcast::routes(['middleware' => 'auth:admin']);
require base_path('routes/channels.php');
}
This link explains more what's going on.
I added below code to routes/web.php and it worked.
Route::post('/broadcasting/auth', function () {
return Auth::user();
});
I Have faced same problem and this trick save my life.
go to api.php
Broadcast::routes(['predix' => 'api', 'middleware' => ['auth:api']]);

Authorization for laravel passport through websocket

I have a private channel. And i can use it only if i authenticated on site. But in case of laravel passport i have no idea how it should be work. By default all what i need contains in cookies.
What i have:
Broadcast::routes();
Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});
Broadcast::routes(['middleware' => ['api']]); have no effect.
How do I authenticate users through laravel passport, for that would be connected to a private channel websocket?
I been through this, and my solution was using Laravel Echo & Laravel Echo Server for SocketIo.
Retrieve the user access token, then store it in cookie or application storage, and inject it while you instantiating or re-instantiating Laravel Echo, like the following:
let Echo = require('laravel-echo')
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
auth: {
headers: {
Authorization: 'Bearer ' + AUTH_API_TOKEN,
},
},
});
References:
https://laravel.com/docs/5.3/broadcasting#driver-prerequisites
https://github.com/tlaverdure/laravel-echo-server
Unfortunately at the current moment the echo does not support authorization with the help of laravel passport, it is necessary to write your own sokket.io server.

Resources