【问题标题】:Laravel broadcasting auth route simply returns "true"Laravel 广播身份验证路由只返回“true”
【发布时间】:2018-01-03 20:03:07
【问题描述】:

我在 Laravel 5.3 中设置并初始化了我的按键。当我在本地环境中测试它时,它可以工作。当我尝试在我们的生产环境中运行完全相同的代码时,我收到了这个错误:

Pusher : Error : {"type":"WebSocketError","error":{"type":"PusherError","data":{"code":null,"message":"Auth info required to subscribe to private-App.User.16"}}}

我已经确认我的本地和生产中的 Pusher 键是相同的。

WS 在两个环境中初始化相同:

wss://ws.pusherapp.com/app/264P9d412196d622od64d?protocol=7&client=js&version=4.1.0&flash=false

我能看到的唯一区别是,当我们的生产服务器联系 Laravel“广播/认证”路由时,它只是在响应正文中收到 true

当我的本地联系人“广播/身份验证”时,它会在响应中得到以下信息:

{auth: "22459d41299d6228d64d:df5d393fe37df0k3832fa5556098307f145d7e483c07974d8e7b2609200483f8"}

在我的BroadcastServiceProvider.php:

public function boot()
{
    Broadcast::routes();

    // Authenticate the user's personal channel.
    Broadcast::channel('App.User.*', function (User $user, $user_id) {
        return (int)$user->id === (int)$user_id;
    });
}

什么可能导致 broadcast/auth 路由仅返回 true 而不是预期的身份验证?

【问题讨论】:

  • 不应该在route/channels.php 上吗? Link
  • @AntoniosTsimourtos 适用于 Laravel 5.3 之后的版本。
  • 这是基本的,但我想值得一问:您是否使用composer.lock 来确保您在两个环境中具有相同的 deps?
  • 我会尝试找出处理broadcasting/auth请求的方法,然后调试它。

标签: php laravel laravel-5.3 pusher


【解决方案1】:

如果您检查PusherBroadcaster.php 文件,您会看到响应可以“混合”。

我认为文档只是在说默认广播。

通道方法接受两个参数:通道名称和 返回 true 或 false 的回调,指示用户是否 授权收听频道。

这是PusherBroadcast 中的validAuthenticationResponse 方法。

/**
 * Return the valid authentication response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  mixed  $result
 * @return mixed
 */
public function validAuthenticationResponse($request, $result)
{
    if (Str::startsWith($request->channel_name, 'private')) {
        return $this->decodePusherResponse(
            $this->pusher->socket_auth($request->channel_name, $request->socket_id)
        );
    }

    return $this->decodePusherResponse(
        $this->pusher->presence_auth(
            $request->channel_name, $request->socket_id, $request->user()->getAuthIdentifier(), $result)
    );
}

再举一个例子,这是在RedisBroadcast 里面。

if (is_bool($result)) {
    return json_encode($result);
}

关于此“身份验证请求”的简短说明:

BroadcastManager 实例化所有“可用驱动程序”(Pusher、Redis、Log 等),并创建“auth”路由(使用 BroadcastController + authenticate 方法)。

当你调用“auth”时,会发生这种情况:

  1. 调用“broadc.../auth”路由。
  2. BroadcastManager 将实例化正确的驱动程序(在您的情况下为 Pusher
  3. PusherBroadcaster 可以抛出异常 AccessDeniedHttpException 如果用户未通过身份验证(“用户会话” - Auth::user() 未定义/为空)并且正在尝试访问私有(或存在)通道类型。
  4. 如果用户尝试访问 private/presence 频道并且用户已通过身份验证 (Auth::check()),Laravel 将检查 auth.用户可以访问该频道。 (检查:verifyUserCanAccessChannel 方法)。
  5. 之后,validAuthenticationResponse 方法将被调用。此方法将使用用户凭据向推送器发出请求并返回一个数组。此数组包含 Pusher 响应(套接字身份验证:https://github.com/pusher/pusher-http-php/blob/03d3417748fc70a889c97271e25e282ff1ff0ae3/src/Pusher.php#L586 / Presence 身份验证:https://github.com/pusher/pusher-http-php/blob/03d3417748fc70a889c97271e25e282ff1ff0ae3/src/Pusher.php#L615),它是一个字符串。

简答

Soo.. Pusher 需要此身份验证响应。否则您将无法连接/识别用户 (wss://ws.pusherapp.com....)。

【讨论】:

  • 感谢您的详细解释。这为我指明了正确的方向,但为什么 validAuthenticationResponse 中的 $result 可能是 Pusher 在不同环境中的布尔响应?
  • BROADCAST_DRIVER=redis 在您的生产中 .env 文件 VS BROADCAST_DRIVER=pusher 本地。
【解决方案2】:

编辑这是来自 5.5 版的文档,此处不适用。

我认为问题可能在于在频道名称中使用“*”通配符。

我在本地和生产中都使用以下内容:

Broadcast::channel("servers.{id}", function (Authenticatable $user, $id) {
    return (int)$user->getAuthIdentifier() === (int)$id;
});

【讨论】:

  • 这很奇怪,因为documentation 另有说明。
  • 我的错,我忽略了他指出 5.3 作为版本。这是 5.5 版的。
【解决方案3】:

出现问题是因为您没有在生产的.env 文件中设置正确的BROADCAST_DRIVER(默认为redis)。

# before
BROADCAST_DRIVER=redis

# after
BROADCAST_DRIVER=pusher

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 2018-07-14
    • 2021-01-01
    • 2016-02-05
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 2013-05-16
    相关资源
    最近更新 更多