React Native Pusher - 使用 Laravel Passport OAuth 订阅私有频道 - HTTP 响应详情

3

当我尝试在我的React Native应用程序中使用Pusher订阅私有频道时,会持续出现500错误。后端是带有Passport OAuth服务器的Laravel。

我已在我的Pusher设置中设置了授权端点(http://url/broadcasting/auth)。

React Native Pusher设置

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);
});

我尝试在我的routes/channels.php文件中添加广播授权路由,并使用一个回调函数返回true,但是我一直遇到500错误。

routes/channels.php

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

以下是事件类

<?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');
    }
}

来自控制台的反馈信息:“Pusher:无法从您的Web应用程序获取身份验证信息:500”对于调试并不是真正有用的。很难指出问题出在哪里。如果您有任何想法呢?
如果没有,我怎么能从pusher响应的http响应中获得更多信息/反馈呢?
谢谢。
编辑:
根据下面的回答,我已更新了路由。请注意api / *路由没有csrf令牌检查,因为我将它们从中间件中排除。
仍然收到500个错误。是否有任何方法可以获得有关Pusher引发的错误的更多详细信息?有一些更多的反馈是有用的,以了解正在发生什么。
新的认证端点:
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');

编辑 2:

我通过移除授权中间件使其正常工作。

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

});

但是很显然,这个想法是为了能够让用户发出这样的请求,以便我可以给予适当的授权。

以下是我如何从react-native传递我的身份验证令牌来调用pusher,但我得到了401响应。

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

我使用上面给出的中间件和令牌进行的所有 OAuth GET 和 POST 请求都正常工作,但是出现了以上错误信息。你有什么想法吗?

2个回答

3

将您的认证端点编辑为以下方式

        $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;
        }

2

认证端点不能简单地返回true。它必须返回由您服务器上的Pusher库生成的特殊令牌。客户端使用此令牌向Pusher API证明它有权连接到私有频道。请查看此文档


谢谢你的回答,但我还是卡住了。我已经根据你的建议编辑了我的帖子(请求包括channel_name和socket_id对吗?)。但到目前为止还没有运气。当我在我的Web应用程序中使用私有频道时,使用我上面展示的初始实现在私有频道上进行身份验证没有问题。我认为问题在于Web应用程序无法识别有用户登录,因为它正在使用Laravel Passport OAuth实现。有什么想法吗? - sbkl
很抱歉,我不太明白你所说的“当我在我的Web应用程序中使用私有频道时,使用我上面展示的初始实现对私有频道进行身份验证时没有任何问题。”的意思。你能否检查浏览器的调试控制台的网络选项卡,看看你的认证终点返回了什么? - leesio
当我在没有OAuth服务器的情况下使用我的网站的常规JavaScript客户端进行注册时,我使用Laravel Echo。如果我的解释不清楚,请见谅。这是我遵循的文档:https://laravel.com/docs/5.4/broadcasting#installing-laravel-echo - sbkl
我通过在请求中删除用于用户身份验证的oauth中间件使其正常工作。这是一个很好的第一步。但现在的问题是,我需要能够获取用户的身份验证,以便可以对频道的访问进行适当的授权...不确定我是否正确地传递了oauth令牌到pusher请求中? - sbkl
问题出在我这边。我获取令牌的方式有误,因此导致了身份验证问题。所以上面的代码是有效的。感谢您的帮助。 - sbkl
@sbkl 我和你一样卡在同一个点上。好的,pusher库在调用/broadcasting/auth后返回一个令牌,但是Laravel Echo在浏览器中没有订阅该频道。你知道如何解决这个问题吗? - Mikel Granero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接