Laravel Broadcast - 结合多个中间件(web,auth:api)

时间:2018-02-22 18:35:07

标签: laravel middleware laravel-5.5 laravel-passport laravel-events

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

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 个答案:

答案 0 :(得分:3)

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

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

    Broadcast::routes(['prefix' => 'api', 'middleware' => 'api']);

答案 1 :(得分:2)

我终于想出了怎么做。

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

我是如何实现的,为'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)在我的路线中创建了除Laravel / broadcast / auth之外的唯一路线&gt; web.php

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>

答案 2 :(得分:1)

我最好只使用扩展到auth:apiweb中间件的中间件。

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

答案 3 :(得分:0)

广播服务提供者

if (request()->hasHeader('authorization')){
    Broadcast::routes(['middleware' => 'auth:api']);
} else {
    Broadcast::routes();
}