Skip to content
Advertisement

Laravel Pusher 401 Unauthorized

I cannot get my events working on laravel 7.x, pusher, laravel-echo. I have set up everything correctly but still getting 401 error. I have also set up broadcast_driver as pusher in .env file. If anyone can help, I will appreciate.

CommentEvent.php

<?php

namespace AppEvents;

use IlluminateBroadcastingChannel;
use IlluminateBroadcastingInteractsWithSockets;
use IlluminateBroadcastingPresenceChannel;
use IlluminateBroadcastingPrivateChannel;
use IlluminateContractsBroadcastingShouldBroadcast;
use IlluminateFoundationEventsDispatchable;
use IlluminateQueueSerializesModels;

class CommentEvent implements ShouldBroadcast

{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $comment;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($comment)
    {
        $this->comment =$comment;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return IlluminateBroadcastingChannel|array
     */
    public function broadcastOn()
    {
        return new Channel('comment-channel');
    }

    public function broadcastAs()
        {
            return 'newComment';
        }
}

CommentController.php

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppEventsCommentEvent;
use AppComment;

class CommentController extends Controller
{
   public function index(){
      return view('comments');
   }

   public function fetchComments(){
      $comments =Comment::all();

      return response()->json($comments);
   }

   public function store(Request $request){
      $comment =Comment::create($request->all());

      event(new CommentEvent($comment));

      return response()->json('ok');
   }
}

/routes/channels.php

<?php

use IlluminateSupportFacadesBroadcast;

/*
|--------------------------------------------------------------------------
| Broadcast Channels
|--------------------------------------------------------------------------
|
| Here you may register all of the event broadcasting channels that your
| application supports. The given channel authorization callbacks are
| used to check if an authenticated user can listen to the channel.
|
*/

// Broadcast::channel('App.User.{id}', function ($user, $id) {
//     return (int) $user->id === (int) $id;
// });

Broadcast::channel('comment-channel', function () {
    return true;
});

bootstrap.js

window._ = require('lodash');


try {
    window.Popper = require('popper.js').default;
    window.$ = window.jQuery = require('jquery');

    require('bootstrap');
} catch (e) {}



window.axios = require('axios');
window.moment = require('moment');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
window.axios.defaults.headers.common.crossDomain = true;
// window.axios.defaults.baseURL = '/api';

    let token = document.head.querySelector('meta[name="csrf-token"]');

    if (token) {
        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
    } else {
        console.error('CSRF token not found: https://adonisjs.com/docs/4.1/csrf');
    }



import Echo from 'laravel-echo';

window.Pusher = require('pusher-js');

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: process.env.MIX_PUSHER_APP_KEY,
    cluster: process.env.MIX_PUSHER_APP_CLUSTER,
    forceTLS: true
});

store.js

import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex);

export const store =new Vuex.Store({
    state:{
        //stores all the comments in this array//
        comments:[]
    },
    getters:{
        //returns the comments array//
        comments:state=>{
            return state.comments
        }
    },
    mutations:{
        //populates the comments array in the state with the comments from the database//
        getComments:(state,comments)=>{
            state.comments =comments
        },
        addComment:(state,comment)=>{
            state.comments = state.push(comment)
        }
    },
    actions:{
        /* gets all the comments from comments endpoint api*/
       getComments:({commit})=>{
           axios.get(`http://127.0.0.1:8000/api/comments`)
             .then(res=>{
                 //commits getcomments mutation and passes a parameter of comments from the response//
                 commit('getComments',res.data)
                 
             })
             .catch(err=>{
                 console.log(err)
             })
       },
       addComment:({commit},comment)=>{
         return new Promise((resolve,reject)=>{
             axios.post(`http://127.0.0.1:8000/api/comments`,{
                 author:comment.author,
                 content:comment.content
             })
                .then(res=>{
                    resolve(res)
                }).catch(err=>{
                    reject(err)
                })
         })
       }
    }
})

MainApp.vue

<template>
      <div class="container">
          <div class="row">
             <div class="col">
                 <div class="card">
                     <div class="card-body">
                         <form @keyup.enter="postComment">
                           <div class="form-group">
                             <input type="text" class="form-control" placeholder="Author's Name" v-model="comment.author">
                         </div>
                         <div class="form-group">
                             <textarea name="comment" id=""  rows="6" class="form-control" v-model="comment.content" >

                             </textarea>
                         </div>
                         <div class="form-group">
                             <input type="submit" value="Submit" class="btn btn-success" @click.prevent="postComment">
                         </div>
                         </form>
                         
                     </div>
                 </div>

             </div>
        <div class="col">
            <div class="card">
                <div class="card-body">
                    <div class="media" v-for="comment in comments" :key="comment.id">
                 <img class="mr-3" src="https://api.adorable.io/avatars/48/@adorable.io.png" alt="Generic placeholder image">
               <div class="media-body">
                   <h5>{{comment.author}}</h5>
                   {{comment.content}}
               </div>
          </div>
                </div>
            </div>
            
        </div>
          </div>

          
      </div>
</template>

<script>
  import {store} from '../store';
  import {mapGetters} from 'vuex';
  import {mapActions} from 'vuex';
  

    export default {
       store:store,

       data:function(){
           return{
               comment:{
                   author:'',
                   content:''
               }
           }
       },

        mounted() {
            //calls the action getcomments from store.js//
            this.$store.dispatch('getComments');
           
             Echo.channel('comment-channel')
                .listen('.newComment', (e)=>{
                   console.log(e)
                })
        
        },

        computed:{
            //gets the comments array from store.js//
           ...mapGetters([
               'comments'
           ])
        },

        methods:{
            postComment:function(){
                
                this.$store.dispatch('addComment',this.comment)
                  .then(res=>{
                      if(res==='ok'){
                          console.log('success')
                      }
                  }).catch(err=>{
                      console.log(err)
                  })
            }
        }

        
        
    }
</script>

Advertisement

Answer

Make sure to pass $user into the channel route callback. replace this code with your channel route. then you are good to go 🙂

Broadcast::channel('comment-channel', function ($user) {
    return true;
});
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement