14

我正在用 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);
            });
        });
    }

我试图在中间件中插入这段代码,并进行适当的更正,但我不知道如何使它工作。

4

4 回答 4

40

我没有 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(),它就在那里。

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

于 2016-09-12T06:34:44.487 回答
3

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

Auth 使用 rebinder 来分配userResolveron request。(所以你从中得到$request->user())。检查Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler它如何设置解析器。

$request->setUserResolver(....)
于 2016-09-09T21:48:01.687 回答
2

这是一个非常有用的问题。不过,我在选择的解决方案上遇到了麻烦。在我的中间件中,我可以成功看到 $request->user(),但是在使用门时它失败了,即在 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() 的情况下工作。

谢谢

于 2017-10-23T01:22:49.733 回答
0

如果您有用户 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);
}
于 2020-09-22T15:20:55.363 回答