【问题标题】:How to change Laravel's default broadcast auth middleware如何更改 Laravel 的默认广播授权中间件
【发布时间】:2018-09-07 14:24:26
【问题描述】:

所以,正如我的标题所说,我想将 Laravel 的默认 Broadcast 身份验证中间件更改为我制作的使用基于令牌的身份验证的自定义身份验证中间件。我这样做是因为我的应用程序是基于 API 的应用程序,并且当用户进行身份验证时,我会创建一个会话令牌并将其发送给他,并将其存储在带有 expires_at 列的数据库中。 我正在使用Pusher

我有以下中间件:

class AuthCustom
{
    public function handle($request, Closure $next)
    {
        // if we have the session token stored in header
        if ($request->header('x-session')) {
            $session = Session::where('id', $request->header('x-session'))->where('expires_on', '>=', date('Y-m-d G:i:s'))->with('user')->first();
            if ($session !== null) {
                $user = (new User())->where('id', $session->user_id)->first();
                if ($user !== null) {
                    $request->merge(['user' => $user]);

                    return $next($request);
                }
            }
        }
}

我的BroadcastServiceProvider代码如下:

class BroadcastServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Broadcast::routes();

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

如果我将Broadcast::routes(['middleware' => 'authcustom']); 放在BroadcastServiceProvider 中,boradcasting/auth 会给出403 状态代码,因为$request->user() 为空,这会导致Access forbidden

我已经尝试搜索整个该死的网络,但我没有发现有关更改广播的默认身份验证中间件的任何信息。

我什至尝试删除 Broadcast::routes() 并自定义一条新路由 /broadcast,它返回一个 Pusher socket_auth 对象,每次我得到一个 419 Unkown 状态码。

有什么想法,或者您可以指出我可以解决这个问题的方向吗? 谢谢!

后期编辑: 我的 JS Echo 连接如下所示:

Vue.use(VueEcho, {
    broadcaster: 'pusher',
    key: 'xxxxxxxxxxxxxx',
    cluster: 'eu',
    authEndpoint: 'http://localhost/api.easycargo.ro/public/broadcasting/auth',
    auth: {
        headers: {
            'x-session': this.auth.token
        }
    }
});

【问题讨论】:

  • 可能不是问题:只是指出date('Y-m-d G:i:s') 这是我第一次看到有人使用G 而不是H 我不确定MySQL(或任何数据库)是否可以返回日期正确。
  • @cbaconnier 不用担心,它的工作原理就是这样
  • 你可以使用 laravel 护照。这是 laravel 的 API 认证的默认设置。 laravel.com/docs/5.6/passport
  • @SjoerddeWit 嗯,好点,不知道 Laravel 的功能。感谢您指出这一点。

标签: php laravel broadcast laravel-5.6 pusher


【解决方案1】:

我很高兴你有一些工作。对于以后的读者,这里有一个更 Laravel 式的方法来解决问题中的问题:创建一个 custom auth guard 用于对特殊路由的请求进行身份验证。

Laravel 的 AuthManager 包含一个帮助方法 —viaRequest() — 简化了 Guard 的创建,该方法使用来自请求上下文的数据对用户进行身份验证,而无需完全实现 Illuminate\Contracts\Auth\Guard。我们可以在 AuthServiceProvider.php 中的boot() 方法中绑定我们的自定义守卫:

public function boot()
{
    Auth::viaRequest('custom-auth', function ($request) {
        // Any custom user-lookup logic here. For example:
        if ($request->header('x-session')) {
            $user = // ...try to fetch a user...
            return $user;
        }
    });
}

如我们所见,我们只是将一个闭包传递给viaRequest() 方法,该方法在身份验证成功时返回User 对象,或者在身份验证失败时返回null

接下来,我们将通过在 config/auth.php 中的 'guards' 数组中添加一个条目来告诉 Laravel 我们新的身份验证保护:

'guards' => [ 
    ...
    'broadcasting' => [
        'driver' => 'custom-auth', 
    ],
],

最后,我们需要为应该使用我们自定义的Guard 对用户进行身份验证的任何路由更新中间件。我们可以使用 Laravel 内置的 auth 中间件,并指定应用哪个守卫为 middleware parameter。例如,我们将在问题的BroadcastServiceProvider.php中初始化广播路由:

Broadcast::routes([ 'middleware' => [ 'auth:broadcasting', ... ] ]);

...broadcasting 与我们在 config/auth.php 中分配给自定义 Guard 的名称匹配。

这种方法使我们能够使用 Laravel 的所有 Auth 服务,提供一个更集中的位置来定义我们的身份验证逻辑,并简化自动化测试,因为我们可以根据需要更轻松地模拟身份验证。

【讨论】:

  • 感谢您的替代方法,我今天学到了一些新东西。我会在 30 分钟内给你赏金。
  • @southpaw93 不客气! Passport 也可以帮助解决这种 API 身份验证问题。如果你愿意,你可以暂时搁置赏金——有人可能有比我更好的主意。我总是喜欢看到替代品。
  • Broadcast::routes([ 'middleware' => [ 'auth:broadcasting', ... ] ]); 拯救了我的一天。
【解决方案2】:

我实际上设法找到了解决方案,所以我需要做的就是通过执行以下操作将我在自定义 auth 中间件中获得的 $user 绑定到请求:

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

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

现在 $request->user() laravel 检查返回用户对象并通过验证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-14
    • 2018-04-13
    • 2018-10-10
    • 2019-02-21
    • 2019-08-28
    • 2015-05-14
    相关资源
    最近更新 更多