6

我正在使用 Laravel Event Broadcast 和 Pusher 在我的 API 和 Web 上使用 websocket。如果我单独尝试它们,两者都可以正常工作。我的意思是:

Broadcast::routes(['middleware' => 'web']); // this works for my Laravel website

Broadcast::routes(['middleware' => 'auth:api']); // this works for my api

但是,如果我想像这样同时使用两者:

Broadcast::routes(['middleware' => ['auth:api', 'web']]); // doesn't work

...它对两者都崩溃了,我怀疑它假设我正在尝试为这两个auth:api && web中间件启用。

有没有办法为此使用 OR 类型的语句 ( auth::api || 'web')?如果我想同时使用两者并且如果它通过一个中间件,它会绕过中间件。

请注意,我将 Laravel Passport 用于我的 api。


或者有没有一种方法可以为两者组合并创建一个混合中间件(本质上将检查 api 或 web)?所以我可以使用这样的东西:

Broadcast::routes(['middleware' => 'broadcast']); // or auth:broadcast

更新:

据我了解,如果我创建一个名为 的新中间件broadcast,我可以这样做:

class BroadcastMiddleware() {

  public function handle() {
    $web = Auth::guard('web')->user();
    if ($web) {
        return response()->json($web);
    }

    $api = Auth::guard('api')->user();
    if ($api) {
        return response()->json($api);
    }
    return response()->json('Unauthorized.', 500);
  }
}

但是那我该如何改变/broadcasting/auth路线呢?如果我试试这个:

Route::post('/realtime/auth', function(){
    return true;
})->middleware('broadcast');

这将返回用户对象信息,但是,它应该返回如下内容:auth:"374f7ff42b7da877aa35:c29addedec281b418331a61dc3cfc74da8b108222565fa4924a8..."

4

4 回答 4

10

为什么不在 BroadcastServiceProvider 中使用类似的东西?这将创建两个单独的端点,并分配了单独的中间件。

    Broadcast::routes(['middleware' => 'web']);

    Broadcast::routes(['prefix' => 'api', 'middleware' => 'api']);
于 2018-09-11T08:36:08.370 回答
4

我终于想出了怎么做。

我不确定这是否是实现这一目标的最佳方式,我非常感谢任何改进

我如何实现的是为“web”创建了一个新的中间件,并将另一个留给它。以下是步骤。

1) 在“BroadcastServiceProvider”中,只auth:api保留Broadcast::routes(['middleware' => 'auth:api']);.

这样,Laravel 的auth:api广播认证方法就可以正常工作了。

2) 创建一个名为“Broadcast”的中间件并将其映射到 Kernel.php 中,如下所示:

'broadcast' => \App\Http\Middleware\Broadcast::class

Broadcast.php中间件看起来像这样:

public function handle($request, Closure $next)
{
    $web = Auth::guard('web')->user();
    if ($web) {
        return response()->json(\Illuminate\Support\Facades\Broadcast::auth($request));
    }

    return response()->json('Unauthorized.', 500);
}

3) 在我的 routes>web.php 中创建了不同于 Laravel 的 /broadcasting/auth 的唯一路由

Route::post('/guard/broadcast/auth', function(\Illuminate\Support\Facades\Request $req){
    return true;
})->middleware('broadcast');

4)然后只在我的刀片上,我像这样使用它:

<script>

let pusher = new Pusher("{{ env('PUSHER_APP_KEY') }}", {
    cluster: 'us2',
    encrypted: true,
    auth: {
        headers: {
            'X-CSRF-TOKEN': "{{ csrf_token() }}"
        }
    },
    authEndpoint: '{{ env('APP_URL') }}' + '/guard/broadcast/auth',
});

let channel = pusher.subscribe('private-channel.{{ Auth::user()->id }}');

channel.bind('my-event', addMessage);

function addMessage(data) {
    console.log(data);
}

</script>
于 2018-02-23T05:05:24.800 回答
1

我更喜欢只使用扩展到两者的中间件auth:apiweb中间件。

就像我在这里发布的内容:https ://github.com/tlaverdure/laravel-echo-server/issues/266#issuecomment-365599129 。所以,如果我以后想改变它,我只维护 1 个中间件

于 2018-02-24T02:38:22.823 回答
0

广播服务提供者

if (request()->hasHeader('authorization')){
    Broadcast::routes(['middleware' => 'auth:api']);
} else {
    Broadcast::routes();
}
于 2021-02-02T10:19:36.450 回答