sbkl
sbkl

Reputation: 2321

React native pusher - private channel subscription with laravel passport oauth - http response detail

I keep having 500 error when I try to subscribe to a private channel with pusher in my react native app. Back end is laravel with passport oauth server.

I have setup my auth end point in my pusher settings (http://url/broadcasting/auth)

react-native pusher setup

import Pusher from 'pusher-js/react-native';

Pusher.logToConsole = true;

var pusher = new Pusher('pusher-key', {
    authEndpoint:  'http://url.com/broadcasting/auth',
    cluster: 'ap1',
    encrypted: true
});

var channel = pusher.subscribe('private-order');

channel.bind('App\\Events\\Order\\SiteHasAnsweredCheckIn', function(data) {
    console.log('ok : ' + data);
});

and the broadcast authorization route in my routes/channel.php file with a callback simply returning true but I keep having a 500 error

routes/channels.php

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

Here is the event class

<?php

namespace App\Events\Order;

use App\Site;
use App\User;
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 SiteHasAnsweredCheckIn implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $site;

    public $user;

    public $checkInConfirmed;

    /**
     * Create a new event instance.
     *
     * @param Site $site
     * @param User $user
     * @param $checkInConfirmed
     */
    public function __construct(Site $site, User $user, $checkInConfirmed)
    {
        $this->site = $site;

        $this->user = $user;

        $this->checkInConfirmed = $checkInConfirmed;
    }

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

The feedback from the console saying: "Pusher : Couldn't get auth info from your webapp : 500" is not really useful for debbuging. So difficult to point out what is wrong. If you have any idea?

If not, how could I get more information/feedback from the http response from the pusher response?

Thank you.

EDIT:

After the answer below, I have updated the route as follow. Please note api/* routes got no csrf token check as I excluded them from the middleware.

Still get a 500 error. Any way to have more details about the error thrown by Pusher? It would be useful to have some more feedback to understand what is going on.

New auth Endpoint:

Route::post('api/authtest', function() {

    $pusher = new Pusher(config('broadcasting.connections.pusher.key'), config('broadcasting.connections.pusher.secret'), config('broadcasting.connections.pusher.app_id'));
    echo $pusher->socket_auth($_POST[request()->channel_name], $_POST[request()->socket_id]);

})->middleware('auth:api');

EDIT 2:

I made it working by removing the middleware of authorization.

Route::post('api/authtest', function() {

    $pusher = new Pusher(config('broadcasting.connections.pusher.key'), config('broadcasting.connections.pusher.secret'), config('broadcasting.connections.pusher.app_id'));
    echo $pusher->socket_auth($_POST[request()->channel_name], $_POST[request()->socket_id]);

});

But obviously, the idea is to be able to get the user making such request so I can give proper authorization.

Here is how I pass my auth token to the pusher call from react-native but I get a 401 response.

let token = 'auth_access_token_taken_from_database';

var pusher = new Pusher('pasher_key', {
    authEndpoint: 'http://url.com/api/authtest',
    auth: {
        headers: {
            'Accept': 'application/json',
            'Authorization': 'Bearer ' + token
        }
    },
    cluster: 'ap1',
    encrypted: true
});

var channel = pusher.subscribe('private-order');

All my other oauth get and post requests with this middleware and token given above are working properly with my axios calls.

Any idea?

Upvotes: 3

Views: 3604

Answers (2)

Bakhtiar
Bakhtiar

Reputation: 679

edit your auth endpoint like this

        $user = auth()->user();

        if ($user) {
            $pusher = new Pusher('auth-key', 'secret', 'app_id');
            $auth= $pusher->socket_auth(Input::get('channel_name'), Input::get('socket_id'));
            $callback = str_replace('\\', '', $_GET['callback']);
            header('Content-Type: application/javascript');
            echo($callback . '(' . $auth . ');');
            return;
        }else {
            header('', true, 403);
            echo "Forbidden";
            return;
        }

Upvotes: 3

leesio
leesio

Reputation: 741

The authentication endpoint can't simply return true. It must return a special token generated by the pusher library on your server. The client uses this token to demonstrate to the pusher API that it's allowed to connect to the private channel. Check out this documentation.

Upvotes: 2

Related Questions