如何将用户对象绑定到中间件中的请求


How to bind user object to request in a middleware

我正在用Laravel Spark 1.0 (Laravel 5.2)写一个应用程序。我为代理(api)身份验证编写了一个自定义中间件。这是代码:

<?php
namespace App'Http'Middleware;
use App'Agent;
use Closure;
use Illuminate'Http'Request;
class AgentAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  'Illuminate'Http'Request  $request
     * @param  'Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if( isset($request->token) &&  !empty($request->token) )
        {
            $agent = Agent::where('token', '=', $request->token)->first();
            if( $agent != NULL )
            {
                $team = $agent->Team()->first();
                $user = $team->User()->first();
                $request->merge(['team' => $team ]);
                $request->merge(['user' => $user ]);
                return $next($request);
            }
            else {
                return response('Unauthorized 2.', 401);
            }
        }
        else {
            return response('Unauthorized 1.', 401);
        }
    }
}

在默认的laravel认证中,用户对象被注入到请求中(参见laravel文档):https://laravel.com/docs/5.2/authentication#retrieving-the-authenticated-user

所以您可以使用:

检索用户
$request->user();

Spark显然使用这个方法来检查用户订阅是否有效(laravel' Spark 'src'Http'Middleware' verifyuserissubscriptions):

if ($this->subscribed($request->user(), $subscription, $plan, func_num_args() === 2)) {
            return $next($request);
        }

它不工作,因为,与我的中间件,你可以检索用户使用:$request->user;,但不与laravel默认的$request->user();

我应该如何注入用户对象到请求?

提前谢谢你

编辑:

Laravel在服务提供者(Illuminate'Auth'AuthServiceProvider@registerRequestRebindHandler)

使用以下代码将对象user绑定到请求:

/**
     * Register a resolver for the authenticated user.
     *
     * @return void
     */
    protected function registerRequestRebindHandler()
    {
        $this->app->rebinding('request', function ($app, $request) {
            $request->setUserResolver(function ($guard = null) use ($app) {
                return call_user_func($app['auth']->userResolver(), $guard);
            });
        });
    }

我试图插入此代码,适当的纠正,在中间件,但我不知道如何使其工作。

我没有Spark的副本来尝试这个&确保我所做的对你是正确的,但我认为这将有助于:

1)一个假设——我相信你是在说,是的,这一行会让你得到你想要的用户:

$user = $team->User()->first();

,你只是想把它绑定到请求,这样你就可以在你的应用程序中访问这个用户:

$request->user()

2)如果这是真的,那么我所做的就是简化你提供的代码,添加:

$request->merge(['user' => $user ]);
//add this
$request->setUserResolver(function () use ($user) {
    return $user;
});
// if you dump() you can now see the $request has it
dump($request->user());
return $next($request);

我在路由闭包中也有$request->user(),它就在那里。

重新绑定应用程序对我来说有点奇怪,似乎没有必要。我不确定是否真的需要这个

您可以使用auth系统,如果该模型实现了正确的接口,为请求登录它们。

Auth使用rebinder在request上分配userResolver。(所以你得到$request->user())。检查Illuminate'Auth'AuthServiceProvider@registerRequestRebindHandler,看看它是如何设置解析器的。

$request->setUserResolver(....)

这是个很有用的问题。我在选择解决方案时遇到了麻烦。在我的中间件中,我可以成功地看到$request->user(),但是它在使用Gate时失败,即在Access/Gate类中:

protected function raw($ability, $arguments = [])
{
    if (! $user = $this->resolveUser()) {
        return false;
    }
    // ...

这个函数总是返回false:/

所以我按照这里(http://laravel-recipes.com/recipes/230/setting-the-currently-authenticated-user)的建议做了,即:

$usr = new User();
$usr->setAttribute('id', $request->user_id);
Auth::setUser($usr);

它似乎没有使用setUserResolver()工作。

谢谢

如果您有用户ID,您可以轻松地使用'Illuminate'Support'Facades'Auth::onceUsingId($user_id)验证用户

更新$request对象。例如:

public function test(Request $request)
{
    Auth::onceUsingId(19);
    $next = new 'App'Http'Controllers'OtherController();
    return $next->otherMethod($request);
}