laravel 如何在中间件中将用户对象绑定到请求
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39414776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to bind user object to request in a middleware
提问by eldblz
i'm writing an application in Laravel Spark 1.0 (Laravel 5.2). I wrote a custom middleware for agent (api) authentication. This is the code:
我正在 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);
}
}
}
In the default laravel authentication the user object is injected in the request (see laravel docs): https://laravel.com/docs/5.2/authentication#retrieving-the-authenticated-user
在默认的 Laravel 身份验证中,用户对象被注入到请求中(参见 Laravel 文档):https://laravel.com/docs/5.2/authentication#retrieving-the-authenticated-user
So you can retrieve the user using:
因此,您可以使用以下方法检索用户:
$request->user();
Spark obviously use this method to check if user subscription is valid (laravel\spark\src\Http\Middleware\VerifyUserIsSubscribed):
Spark 显然使用这种方法来检查用户订阅是否有效(laravel\spark\src\Http\Middleware\VerifyUserIsSubscribed):
if ($this->subscribed($request->user(), $subscription, $plan, func_num_args() === 2)) {
return $next($request);
}
And it's not working because, with my middleware, you can retrieve the user using: $request->user;
but not with the laravel defaults $request->user();
它不起作用,因为使用我的中间件,您可以使用以下方法检索用户:$request->user;
但不能使用 laravel 默认值$request->user();
How should i inject the user object into the request?
我应该如何将用户对象注入到请求中?
Thank you in advance
先感谢您
EDIT:
编辑:
Laravel in the service provider (Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler)
Laravel 中的服务提供者(Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler)
Use this code to bind object user to the request:
使用此代码将对象用户绑定到请求:
/**
* 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);
});
});
}
I tried to insert this code, with the appropriate correction, in the middleware but i can't figure out how to make it work.
我尝试在中间件中插入此代码并进行适当的更正,但我不知道如何使其工作。
回答by jmadsen
I don't have a copy of Spark to try this & ensure what I'm doing is correct for you, but I think this will help:
我没有 Spark 的副本来尝试这个并确保我所做的对你来说是正确的,但我认为这会有所帮助:
1) An assumption - I believe you are saying that yes, this line will get you the user you want:
1)假设 - 我相信你是说是的,这条线会让你得到你想要的用户:
$user = $team->User()->first();
$user = $team->User()->first();
and you merely want to bind it to the request so that you can access this user later in your app via:
并且您只想将其绑定到请求,以便您稍后可以通过以下方式在您的应用程序中访问此用户:
$request->user()
$request->user()
2) If this is true, then all I did was simplify the code you provided to add:
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);
I also $request->user() in the route closure, and it is there.
我还在路由关闭中 $request->user() ,它就在那里。
The app rebinding was a little strange to me, and didn't seem necessary. I'm not sure that anything would really need this for what you are doing.
重新绑定应用程序对我来说有点奇怪,似乎没有必要。我不确定你正在做的事情是否真的需要这个。
回答by lagbox
You could use the auth
system if that model implements the right interface, to log them in for the request.
auth
如果该模型实现了正确的接口,您可以使用该系统来登录它们以进行请求。
Auth uses a rebinder to assign the userResolver
on request
. (So you get $request->user()
from it). Check Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler
to see how its setting that resolver.
Auth 使用重新绑定器来分配userResolver
on request
。(所以你从中得到$request->user()
)。检查Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler
以查看其如何设置该解析器。
$request->setUserResolver(....)
回答by mils
This is a very useful question. I was having trouble with the selected solution though. In my middleware I could successfully see $request->user(), however it was failing when using gates, namely in the Access/Gate class:
这是一个非常有用的问题。不过,我在选择解决方案时遇到了问题。在我的中间件中,我可以成功地看到 $request->user(),但是在使用门时失败了,即在 Access/Gate 类中:
protected function raw($ability, $arguments = [])
{
if (! $user = $this->resolveUser()) {
return false;
}
// ...
This function is always returning false :/
此函数始终返回 false :/
So I did it as suggested here (http://laravel-recipes.com/recipes/230/setting-the-currently-authenticated-user), namely:
所以我按照这里的建议做了(http://laravel-recipes.com/recipes/230/setting-the-currently-authenticated-user),即:
$usr = new User();
$usr->setAttribute('id', $request->user_id);
Auth::setUser($usr);
And it appears to be working without using setUserResolver().
它似乎在不使用 setUserResolver() 的情况下工作。
Thanks
谢谢