无法重新绑定$ request-> setUserResolver

时间:2017-10-25 15:04:00

标签: php laravel laravel-5 lumen

我试图重新绑定$request->user()返回的内容,并且通过内置的身份验证代码,我发现使用app->rebindingrequest->setUserResolver的服务是&#39完成了吗?我自己试了一下,没有运气。我创建了一个服务(好吧,合作的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。

3 个答案:

答案 0 :(得分:0)

在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行即可注册您的提供商;不要修改vendor文件夹中的代码(如果我理解你正在这样做的话)。

更新

我现在明白你的意思,虽然我不确定它真的太多了#34;加载"用于auth / guard方法。 但是,为了创建最小的实现,我认为解决方案将覆盖prepareRequest类的Application方法。

bootstrap/app.php替换

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

$app = new class (realpath(__DIR__.'/../')) extends Laravel\Lumen\Application {
    protected function prepareRequest(\Symfony\Component\HttpFoundation\Request $request)
    {
        if (! $request instanceof Illuminate\Http\Request) {
            $request = Illuminate\Http\Request::createFromBase($request);
        }

        $request->setUserResolver(function () use ($request) {
            return $request->bearerToken();
        })->setRouteResolver(function () {
            return $this->currentRoute;
        });

        return $request;
    }
};

通过这种方式,您可以使用简单的解析逻辑来获取持有者令牌(不要包含AuthServiceProvider)。

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

答案 1 :(得分:0)

不需要来更改onBindViewHolder功能。 只需取消注释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()
  

您可以在请求标头或查询字符串中使用API​​令牌,在请求中使用承载令牌,或使用您的应用程序所需的任何其他方法。

之后,您可以像这样检索经过身份验证的用户:

$this->app['auth']->viaRequest('api', function ($request) {
    if ($request->input('api_token')) {
        return User::where('api_token', $request->input('api_token'))->first();
    }
});

答案 2 :(得分:0)

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

$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根本不会被调用。

附加

您可以使用refresh方法(注册reboundCallbacks)并结合extend方法(以反弹)来获得更干净的代码:

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