Php 无法重新绑定$request->;setUserResolver

Php 无法重新绑定$request->;setUserResolver,php,laravel,laravel-5,lumen,Php,Laravel,Laravel 5,Lumen,我正在尝试重新绑定$request->user()返回的内容,在浏览了内置的身份验证代码后,我发现了一个使用app->rebinding到request->setUserResolver的服务,它是如何完成的?我自己试过,运气不好。我创建了一个服务(很好,是coopted AuthServiceProvider,并将注册表更改为: public function register() { $this->app->rebinding('request', function ($

我正在尝试重新绑定
$request->user()
返回的内容,在浏览了内置的身份验证代码后,我发现了一个使用
app->rebinding
request->setUserResolver
的服务,它是如何完成的?我自己试过,运气不好。我创建了一个服务(很好,是coopted AuthServiceProvider,并将注册表更改为:

public function register()
{
    $this->app->rebinding('request', function ($app, $request) {
        $request->setUserResolver(function () use ($app) {
            $token = $this->request->bearerToken();
            dd($token);
            // error_log($token);
            return array('user' => 1);
        });
    });
}
忽略要测试的dd,我如何才能找到我的错误所在?我甚至找到了一个SO答案,似乎表明这是正确的方法,但没有任何内容被转储,没有任何内容被记录(当错误日志未被注释掉时),并且在我的控制器中转储
$request->user()
只返回null

我知道我可以使用内置的auth/guard设置,但我想既然我没有使用auth/guard设置的大部分功能,为什么不自己尝试学习和设置它呢?当然,到目前为止,我还没有取得任何进展。我打算使用内置的东西,但我想学习和改进


我意识到这可能会有所不同,我正在运行Lumen 5.4。

在Lumen中,您的
App\Providers\AuthServiceProvider
类默认带有

public function boot()
{
    // Here you may define how you wish users to be authenticated for your Lumen
    // application. The callback which receives the incoming request instance
    // should return either a User instance or null. You're free to obtain
    // the User instance via an API token or any other method necessary.
    $this->app['auth']->viaRequest('api', function ($request) {
        if ($request->input('api_token')) {
            return User::where('api_token', $request->input('api_token'))->first();
        }
    });
}
这是定义用户解析逻辑的地方。您在
register
方法中注册的重新绑定由此方法代替

只需取消注释
$app->register(app\Providers\AuthServiceProvider::class);
bootstrap/app.php
中的
行即可注册您的提供商;不要修改
供应商
文件夹中的代码(如果我理解正确,您正在这样做)


更新

我现在明白你的意思了,尽管我不确定auth/guard方法的“负载”是否太大。 但是,为了创建一个最小的实现,我认为解决方案应该覆盖
应用程序
类的
prepareRequest
方法

bootstrap/app.php中
replace

$app = new Laravel\Lumen\Application(
    realpath(__DIR__.'/../')
);

通过这种方式,您可以获得获取承载令牌的简单解析逻辑(不包括AuthServiceProvider)


(这需要PHP7匿名类;或者只扩展到常规类)。

您不需要更改
register()
函数。 只需取消注释
bootstrap/app.php
文件中的以下行:

$app->withEloquent();
$app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
$app->routeMiddleware([
    'auth' => App\Http\Middleware\Authenticate::class,
]);
app/Providers/AuthServiceProvider.php->boot()
中,它具有检索经过身份验证的用户的默认方法

$this->app['auth']->viaRequest('api', function ($request) {
    if ($request->input('api_token')) {
        return User::where('api_token', $request->input('api_token'))->first();
    }
});
您可以在请求头或查询字符串中使用API令牌,在请求中使用承载令牌,或者使用应用程序需要的任何其他方法

之后,您可以如下方式检索经过身份验证的用户:

use Illuminate\Http\Request;

$app->get('/post/{id}', ['middleware' => 'auth', function (Request $request, $id) {
    $user = Auth::user();

    $user = $request->user();

    //
}]);

rebinding
方法将添加一个额外的
rebockCallbacks
,该回调将在摘要反弹后立即触发。只要您的摘要没有反弹,就不会调用
rebockCallbacks
。因此,您可以简单地反弹摘要,如下所示:

$this->app->rebinding('request', function ($app, $request) {
    $request->setUserResolver(function () use ($app) {
        $token = $this->request->bearerToken();

        dd($token);

        // do the rest
    });
});

// REBOUND HERE
$this->app->instance('request', $this->app->make('request'));

// TEST
// $this->app->make('request')->user(); // output is $token
尝试取消注释上面的反弹行,您的
dd
将不会被调用

额外的 您可以使用
刷新
方法(注册
回弹回调
)与
扩展
方法(回弹)相结合来清除代码:

public function register()
{
    parent::register();

    $this->app->refresh('request', $this, 'overrideUserResolver');

    // REBOUND HERE, JUST ANOTHER WAY TO REBOUND
    $this->app->extend('request', function ($request) { return $request; });

    // TEST
    $this->app->make('request')->user();
}

public function overrideUserResolver($request)
{
    $request->setUserResolver(function ($guard = null) use ($request) {
        $token = $request->bearerToken();

        dd($token);

        // do the rest
    });
}

您是否将新的服务提供商添加到
'providers'
中的
config/app.php
?我实际上刚刚删除了现有
AuthServiceProvider
的内容,并将其写入
注册表()
。我不认为这会是个问题吗?哦,我以为你把AuthserviceProvider复制到了新的provider中…不是问题。也请检查。可以为你指出正确的方向谢谢。我之前遇到过,我想我应该自己测试一下。正如前面提到的,希望找出我在学习方面的错误。你能吗提供最少代码git repo来调试问题?好的,
echo
s,
dd
s,
error\u log
s在函数内部从未触发过,因此它甚至不在是否存在请求对象的点上。它实际上从未进入函数内部。正如我提到的,我从内置的
AuthService
架构复制了它。如果可以进入函数,即使请求对象不在那里,我也可以提取我需要的头值。感谢反馈,但正如我在问题末尾提到的,我知道我可以使用内置的auth/guard方法,但我希望了解更多关于Laravel/Lumen如何在引擎盖下工作的信息。我跟踪了
viaRequest
back通过vendor,发现它正在重新绑定
setUserResolver
,所以我想自己尝试一下。我只是在vendor中做了很多更改,以调试它的工作方式。内置的auth/guard功能远远超出了我的需要,所以我想学习它,以便帮助减少总体负载。我正在从vendor中复制代码以创建自己的authviceProvider。非常感谢您提供的详细答案!我一定会深入研究。您的“减少负载”是正确的在这种情况下,可能没有什么意义。我对学习更感兴趣。我仍然想弄清楚为什么内置的AuthService功能与重新绑定一起工作,而我的没有,但这是一个很好的部分。我会尽可能早地进行测试。谢谢,但正如我在回答中提到的,我已经知道我做不到他通过内置的Auth/Guard系统完成了这项工作;我已经阅读了文档,并且已经用这种方式进行了设置。我试图对Laravel/Lumen有更深入的了解,因此我试图推断Auth系统是如何完成这项工作的,这似乎就是我在上面所做的,只是我的方法不起作用。
public function register()
{
    parent::register();

    $this->app->refresh('request', $this, 'overrideUserResolver');

    // REBOUND HERE, JUST ANOTHER WAY TO REBOUND
    $this->app->extend('request', function ($request) { return $request; });

    // TEST
    $this->app->make('request')->user();
}

public function overrideUserResolver($request)
{
    $request->setUserResolver(function ($guard = null) use ($request) {
        $token = $request->bearerToken();

        dd($token);

        // do the rest
    });
}