Laravel Broadcast身份验证

时间:2017-11-01 14:59:51

标签: php laravel socket.io

如何使用自定义身份验证方法向用户验证用户?

例如,在我的应用程序中,我为我的API使用了令牌身份验证(存储在每个用户的数据库中),通过标头传递并由自定义中间件读取。

如何使用这些自定义身份验证方法控制频道访问?如何成为客户端和服务器端?我使用的是socket.io,而且Laravel文档还不清楚auth方法如何适用于套接字。

使用案例

我将用户存储在DB中并使用默认的Laravel迁移。但是,我的应用程序只是API,它是无状态的,然后,我使用它来存储在登录端点中生成的唯一身份验证令牌,而不是使用remember_token来存储会话令牌。

API的每个端点,请求都通过中间件,其中用户通过标头中的令牌检索用户

$token = Request::header('X-token');

$request->user = User::findByToken($token);

return $next($request);

现在问题出现了.Laravel docs对于私人渠道如何运作并不是很清楚。

广播客户端如何通过提及的令牌并获得加入指定频道的授权?

2 个答案:

答案 0 :(得分:6)

Laravel documentation on broadcasting对此非常全面,虽然它没有详细介绍客户端库,但它并不支持开箱即用。

在这种情况下,您需要section on authorizing channels。来自文档:

  

在Laravel应用程序附带的BroadcastServiceProvider中,您会看到对Broadcast::routes方法的调用。此方法将注册/broadcasting/auth路由以处理授权请求

定义广播路由时,当前经过身份验证的用户将自动作为参数传递。由于您希望更改广播路由定义的提前的身份验证机制,以便传递正确的用户,因此您的广播客户端将传递令牌(无论您喜欢 - HTTP头, URL参数,POST数据等)然后您将自定义/broadcasting/auth路由以解析该数据并使用它来验证用户。从那里,您将使用标准Broadcast::channel()定义来确保经过身份验证的用户也是该频道上的授权用户。

根据文档,Broadcast::routes()使用$attributes的可选数组来使用web中间件。来自the source

$attributes = $attributes ?: ['middleware' => ['web']];

因此,如果您愿意,可以将中间件身份验证更改为'api',方法是将其传递给Broadcast::routes()调用(或任何其他标准路由参数)。

the route is already created for you以来,如果您想在路由功能/中间件的较低级别对其进行自定义,那么您需要更改auth()方法,而不是BroadcastProvider。使用。更具体地说,当路线设置时,它calls the authenticate() method on the BroadcastController,而calls the auth() method on the Broadcast facade只是a few providers defined out of the box。然后外观将调用您正在使用的任何提供商 - 如果您想编写自己的提供商,可以为您提供良好的起点。话虽如此,只要您没有提供商本身的问题,如果您需要某些内容,可能更容易编写自己的中间件并将其作为属性传递给Broadcast::routes()特别是您的身份验证(如果它与api身份验证中间件不同)。

另外,由于您已使用Laravel Echo对此进行了标记,因此您可能还需要阅读broadcasting introduction。还有socket.io专门与{{3}}进行对话的部分。

答案 1 :(得分:1)

在Leith的答案之上,那些挠头的人想知道为什么创建自定义中间件并在BroadcastServiceProvider.php中使用它会抛出错误。

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

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

Broadcaster.php内部,有一种名为retrieveUser()的方法,该方法应该return $request->user()是自定义中间件内部成功进行身份验证的结果。

就我而言,我试图将access token传递给API的自定义中间件;并且在对用户进行身份验证之后,我只是传递了原始请求return $next($request)

为使上述代码正常工作,我必须通过user来获取access token模型,然后像这样将其合并到原始请求中

$request->merge(['user' => $user ]);

$request->setUserResolver(function () use ($user) {
    return $user;
});

return $next($request);

因此,retrieveUser()中的Broadcaster.php方法现在可以使用return $request->user()命令检索经过身份验证的用户,并将其作为第一个参数传递给Broadcast::channel方法

Broadcast::channel('private-channel-name', function ($user) {
    // if you get here, you've been authenticated (within a custom middleware)
    return true;
});

享受!