2

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.

Roland
  • 24,554
  • 4
  • 99
  • 97

2 Answers2

3

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.

nmfzone
  • 2,755
  • 1
  • 19
  • 32
  • Thanks for the answer, as I already said I have tried everything possible including csrf token and also I have tried using laravel-echo but I am getting the same response. The only thing that I don't have tried is the 2nd step. But you are saying it is not recommended. Are you sure that is important to use that? – Roland Jan 05 '19 at 19:44
  • @roliroli No, you don't say it. You just said "I've google it for hours", and in your code, you didn't pass any CSRF token, so I guess you don't aware with that, then my answer based on that. – nmfzone Jan 05 '19 at 20:02
  • @roliroli Anyway, if you said you've already tried solution number 1 and 3, and still didn't work, I guess you didn't have the correct setup. It will be more clear if you provide more code (or reproduction link). – nmfzone Jan 05 '19 at 20:24
  • yes I didn't said that I have everything possible, but indeed I did. What do you mean I don't have the correct setup? Are you talking about the backend? because the BE is successfully triggering the event. – Roland Jan 06 '19 at 08:19
2

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']]);

Roland
  • 24,554
  • 4
  • 99
  • 97
  • Oh, nice. I just realize that you didn't use Laravel Passport. I just guessed before that you use Laravel Passport, so you don't need to pass the auth header. Glad if you found the answer. – nmfzone Jan 06 '19 at 15:28
  • I just want to thank you , you saved my day , it's very useful , and by the way you can use laravel echo, with it , it works perfectly . – allaghi Aug 17 '19 at 11:16
  • Glad to read that you found it helpful.I know that you can use laravel echo but the team didn't wanted to use a package. – Roland Aug 17 '19 at 12:18