React 本机推送器 - 使用 laravel 护照 oauth 的私人频道订阅 - http 响应详细信息

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

当我尝试在我的 React Native 应用程序中使用推送器订阅私人频道时,我一直遇到 500 错误。后端 laravel 带有 passport oauth 服务器。

我已经在推送器设置中设置了我的身份验证端点 (http://url/broadcasting/auth)

react-native 推送器设置

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/channel.php 文件中的广播授权路由,回调仅返回 true 但我一直有 500 错误

routes/channels.php

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

这里是活动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');
    }
}

控制台的反馈说:"Pusher : Couldn't get auth info from your webapp : 500" 对调试没有多大用处。很难指出哪里出了问题。如果你有什么想法?

如果不是,我如何从推送器响应的 http 响应中获得更多 information/feedback?

谢谢。

编辑:

在回答完下面的问题后,我将路线更新如下。请注意 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 的推送器调用,但我收到了 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 使用上面给出的中间件和令牌的请求都可以正常使用我的 axios 调用。

有什么想法吗?

身份验证端点不能简单地 return true。它必须 return 由服务器上的推送程序库生成的特殊令牌。客户端使用此令牌向推送器 API 证明它可以连接到专用频道。看看这个 documentation.

像这样编辑您的身份验证端点

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