Roland
Roland

Reputation: 27729

Pusher with Vue and Laravel API not working

I am using Vue SPA and Laravel. I have google it for hours and tried many things but I can't find a way to make it work.

In index.html I have

<meta name="csrf-token" content="{{ csrf_token() }}"> 

This is my subscribe method:

subscribe() {
  let pusher = new Pusher('key', {
    cluster: 'ap1',
    encrypted: true,
    authEndpoint: 'https://api_url/broadcasting/auth',
    auth: {
      headers: {
        'X-CSRF-Token': document.head.querySelector(
          'meta[name="csrf-token"]'
        )
      }
    }
  })
  let channel = pusher.subscribe(
    'private-user.login.' + this.user.company_id
  )
  channel.bind('UserLogin', data => {
    console.log(data)
  })
}

I am getting a 419 error saying: "expired due to inactivity. Please refresh and try again."

If you didn't noticed there I am trying to listen to a private channel.

Upvotes: 2

Views: 1739

Answers (2)

Roland
Roland

Reputation: 27729

I found the solution I hope it can help others:

In front end:

  let pusher = new Pusher('app_key', {
    cluster: 'ap1',
    encrypted: true,
    authEndpoint: 'https://api_url/broadcasting/auth',
    auth: {
      headers: {
        Authorization: 'Bearer ' + token_here
      }
    }
  })
  let channel = pusher.subscribe(
    'private-channel.' + this.user.id
  )
  channel.bind('event-name', data => {
    console.log(data)
  })

As you can see above no need to use csrf token, instead use the jwt token.

In the backend, go to BroadcastServiceProvider and change this:

Broadcast::routes(); to Broadcast::routes(['middleware' => ['auth:api']]);

Upvotes: 2

nmfzone
nmfzone

Reputation: 2903

419 means you don't pass the CSRF token verification. To solve the issue, there are some way.

  1. You should pass the CSRF token to the Pusher instance. You can follow the instruction here https://pusher.com/docs/authenticating_users. I'll give you an example.

    let pusher = new Pusher('app_key', {
        cluster: 'ap1',
        encrypted: true,
        authEndpoint: 'https://api_url/broadcasting/auth',
        auth: {
            headers: {
                // I assume you have meta named `csrf-token`.
                'X-CSRF-Token': document.head.querySelector('meta[name="csrf-token"]')
            }
        }
     });
    
  2. Disable CSRF verification on the auth broadcasting route. But, this is not recommended, since CSRF verification here is important.

    App\Http\Middleware\VerifyCsrfToken

    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        'broadcasting/auth'
    ];
    
  3. Use laravel-echo, it's behind the scene use axios, you just need to pass CSRF token to the axios header.

    // I assume you have meta named `csrf-token`.
    let token = document.head.querySelector('meta[name="csrf-token"]');
    if (token) {
        window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
    }
    

hope that answer.

Upvotes: 3

Related Questions