我正在使用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..."
答案 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:api
和web
中间件的中间件。
就像我在这里发布的内容: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();
}