gpt4 book ai didi

Laravel Echo + Websockets + 私有(private) channel

转载 作者:行者123 更新时间:2023-12-05 09:36:01 25 4
gpt4 key购买 nike

我知道我不是第一个遇到这个问题的人。但是几天后,我问了很多相关的问题,我觉得我的案子值得单独提问 :)。

我有一个适用于公共(public) channel 的 Laravel Websockets ( https://beyondco.de/docs/laravel-websockets/getting-started/introduction ) 和 Laravel Echo 的工作 websocket 解决方案。我的客户端应用程序是一个 vue-cli 应用程序,连接到服务器 + 在公共(public) channel 上广播消息效果很好。授权由 Laravel Passport 处理。因此,通过在 Authorization header 中发送 Bearer token ,后端应用程序知道用户是否已通过身份验证。

但是,我正在努力让私有(private) channel 正常工作。尝试进行身份验证总是给我这个错误:

Access to XMLHttpRequest at 'https://my-app.test/broadcasting/auth' from origin 'https://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我知道这个 CORS 错误是在我遇到服务器问题时出现的,所以我尝试在 Insomnia 中调试请求。然而,当在 Insomnia 中模仿请求时,它会给出响应 200 以及预期的结果:

Mimick auth request in Insomnia

我一直在阅读一些指南和 stackoverflow 问题,但我找不到任何类似的内容。回到它可能是一个 CORS 问题,但我认为情况并非如此。我的 OPTIONS 请求返回正常。

为了完整起见,我还添加了一些可能有助于调试的代码。

我的广播服务提供商

public function boot()
{
Broadcast::routes(['middleware' => ['auth:api']]);

require base_path('routes/channels.php');
}

我的 channel .php

use Illuminate\Support\Facades\Broadcast;

Broadcast::channel('App.User.{id}', function ($user, $id) {
return (int) $user->id === (int) $id;
});

客户端

this.echoClient = new Echo({
broadcaster: 'pusher',
key: process.env.VUE_APP_WEBSOCKETS_APP_ID,
wsHost: process.env.VUE_APP_WEBSOCKETS_URL,
wssPort: 6001,
// forceTLS: true,
disableStats: true,
authEndpoint: process.env.VUE_APP_SERVER_URL + '/broadcasting/auth',
auth: {
headers: {
Authorization: "Bearer " + this.$store.state.auth.auth_token
}
}
})

// this one works!!
this.echoClient.channel('App.User')
.listen('UpdatePosts', (e) => {
console.log('event received')
console.log(e)
})

// private channels don't work ... :'(
this.echoClient.private('App.User.' + this.user.id)
.listen('UpdatePosts', function(e) {
console.log(e)
})

最佳答案

对于任何正在为这个问题而苦苦挣扎的人。对我来说,解决方案是将 api 前缀添加到 broadcast::auth 方法。

public function boot()
{
Broadcast::routes(['prefix' => 'api', 'middleware' => ['auth:api']]);

require base_path('routes/channels.php');
}

当然你需要在客户端正确设置api前缀:

  authEndpoint: process.env.VUE_APP_SERVER_URL + '/api/broadcasting/auth',

我想不同之处在于,当您为 api Laravel 添加前缀时,我们会特别告诉服务器放弃 web 中间件。

我仍然不太明白为什么 Insomnia 的请求是成功的,因为没有设置 x-csrf header 。 Insomnia 确实发送了一个 cookie header 。也许这就是它在那里工作的原因。

编辑

@Tippin 在 laracasts 论坛上提供的解决方案。

补充一下答案,毕竟这是一个 CORS 问题。

https://github.com/fruitcake/laravel-cors

用 API 为广播路由添加前缀根本不会改变中间件,因此不会将它放在 api 中间件组中。我确实认为正在发生的事情是你可能安装了 cors 包并且在允许的路径中,你有类似 api/* 的东西,所以通过简单地添加该前缀,你解决了你的问题。否则,您可以将默认广播添加到白名单(假设您将该包用于 CORS):

/*
* You can enable CORS for 1 or multiple paths.
* Example: ['api/*']
*/
'paths' => ['api/*', 'broadcasting/auth'],

https://github.com/fruitcake/laravel-cors/blob/master/config/cors.php

关于Laravel Echo + Websockets + 私有(private) channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65437196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com