如何将用户对象绑定到中间件中的请求
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\VerifyUserIsSubscribed):
if ($this->subscribed($request->user(), $subscription, $plan, func_num_args() === 2)) {
return $next($request);
}
它不起作用,因为使用我的中间件,您可以使用以下方法检索用户:$request->user;
但不能使用 laravel 默认值 $request->user();
我应该如何将用户对象注入到请求中?
提前致谢
编辑:
Laravel 在服务提供商 (Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler)
使用此代码将对象用户绑定到请求:
/**
* 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);
});
});
}
我试图在中间件中插入这段代码,并进行适当的更正,但我不知道如何让它工作。
如果该模型实现了正确的接口,您可以使用 auth
系统,让他们登录请求。
Auth 使用重新绑定器将 userResolver
分配给 request
。 (所以你从中得到 $request->user()
)。检查 Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler
以查看其如何设置解析器。
$request->setUserResolver(....)
我没有 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(),它就在那里
应用重新绑定对我来说有点陌生,似乎没有必要。我不确定您正在做的事情是否真的需要这个。
这是一个非常有用的问题。不过,我在选择解决方案时遇到了麻烦。在我的中间件中,我可以成功地看到 $request->user(),但是在使用门时它失败了,即在 Access/Gate class:
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);
}
我正在 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\VerifyUserIsSubscribed):
if ($this->subscribed($request->user(), $subscription, $plan, func_num_args() === 2)) {
return $next($request);
}
它不起作用,因为使用我的中间件,您可以使用以下方法检索用户:$request->user;
但不能使用 laravel 默认值 $request->user();
我应该如何将用户对象注入到请求中?
提前致谢
编辑:
Laravel 在服务提供商 (Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler)
使用此代码将对象用户绑定到请求:
/**
* 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);
});
});
}
我试图在中间件中插入这段代码,并进行适当的更正,但我不知道如何让它工作。
如果该模型实现了正确的接口,您可以使用 auth
系统,让他们登录请求。
Auth 使用重新绑定器将 userResolver
分配给 request
。 (所以你从中得到 $request->user()
)。检查 Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler
以查看其如何设置解析器。
$request->setUserResolver(....)
我没有 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(),它就在那里
应用重新绑定对我来说有点陌生,似乎没有必要。我不确定您正在做的事情是否真的需要这个。
这是一个非常有用的问题。不过,我在选择解决方案时遇到了麻烦。在我的中间件中,我可以成功地看到 $request->user(),但是在使用门时它失败了,即在 Access/Gate class:
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);
}