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
});
}