【问题标题】:Properly inject AuthManager?正确注入 AuthManager?
【发布时间】:2016-06-19 23:46:31
【问题描述】:

我正在使用jwt-auth 库,它使用类型提示注入 AuthManager:

use Illuminate\Auth\AuthManager;
class Basic extends Authorization
{

public function __construct(AuthManager $auth, $identifier = 'email')
    {
        $this->auth = $auth;
        $this->identifier = $identifier;
    }

问题是如果我使用中间件 jwt.auth:

app('Dingo\Api\Routing\Router')->version('v1', ['middleware' => ['jwt.auth'] , 'prefix' => 'api', 'providers' => ['jwt']], function ($api) {
    $api->get('protected', function () {

       $token = JWTAuth::getToken();
       return $token;
    });
});

我收到此错误:

{"message":"Unresolvable dependency resolving [Parameter #0 [ <required> $app ]] in class Illuminate\\Auth\\AuthManager","status_code":500,"debug":{"line":839,"file":"\/share\/vendor\/illuminate\/container\/Container.php","class":"Illuminate\\Contracts\\Container\\BindingResolutionException"

那么,问题是,如何正确注入 AuthManager ?为什么 $app 没有解决?

【问题讨论】:

    标签: laravel lumen


    【解决方案1】:

    尝试在您的bootstrap/app.php 文件中注入AuthManager

    /*
    |--------------------------------------------------------------------------
    | Register Service Providers
    |--------------------------------------------------------------------------
    |
    | Here we will register all of the application's service providers which
    | are used to bind services into the container. Service providers are
    | totally optional, so you are not required to uncomment this line.
    |
    */
    
    $app->register(App\Providers\AppServiceProvider::class);
    $app->register(App\Providers\EventServiceProvider::class);
    
    // Injecting goes here
    $app->singleton(Illuminate\Auth\AuthManager::class, function ($app) {
        return $app->make('auth');
    });
    

    说明

    我们知道如果我们运行Illuminate\Auth\AuthServiceProviderIlluminate\Auth\AuthManager 将被自动解析。见:

    Illuminate\Auth\AuthServiceProvider@registerAuthenticator
    

    所以,我们必须先运行这个服务提供者,然后才能使用AuthManager。但流明略有不同。我看到Illuminate\Auth\AuthManager 还没有注册:

    Laravel\Lumen\Application::$availableBindings
    

    当容器要解析资源时,让 Lumen 运行得更快是一个 hack,参见:

    Laravel\Lumen\Application@make
    

    所以,基本上,如果您想解析Illuminate\Auth\AuthManager 类及其依赖项,您可以在使用它之前先注册它的类绑定。

    更新

    我们知道

    Laravel\Lumen\Application::$availableBindings
    

    属性在 public 可见性中,所以这也有效:

    /*
    |--------------------------------------------------------------------------
    | Register Service Providers
    |--------------------------------------------------------------------------
    |
    | Here we will register all of the application's service providers which
    | are used to bind services into the container. Service providers are
    | totally optional, so you are not required to uncomment this line.
    |
    */
    
    $app->register(App\Providers\AppServiceProvider::class);
    $app->register(App\Providers\EventServiceProvider::class);
    
    $app->availableBindings['Illuminate\Auth\AuthManager'] = 'registerAuthBindings';
    $app->alias('auth', 'Illuminate\Auth\AuthManager');
    

    更新 2

    我知道如果我们想在 Lumen 中使用 this library 实现 JWT 身份验证会有很多问题。因此,我制作了一个与该库很好地集成的引导式(干净启动)流明应用程序。请查看my repo。我将在稍后添加关于哪一个以及为什么我们应该更改代码的解释。干杯。

    【讨论】:

    • $app->singleton(Illuminate\Auth\AuthManager::class, 意味着当使用 AuthManager 时,它会使用相同的实例,但是你能解释一下代码 $app->make ('auth') ?
    • 嗨@simo,我更新了答案。够清楚吗?当您需要更清楚的解释时告诉我,如果您愿意,我会帮助您更深入地研究 Lumen 内核。
    • 非常感谢 Krisa 的解释,我到办公室后会尝试解决方案,我对 OOP 非常有经验,但需要了解更多关于 Laravel 和 lumen 框架的知识。。找不到好的资源关于他们的架构..
    • @simo 很高兴为您提供帮助,先生
    • 嗨@simo,我更新了答案。抱歉回复晚了,我刚到家。如果您需要什么,可以在我的电子邮件中与我联系。我真的很乐意帮助人们。
    【解决方案2】:

    在注册现有的 Laravel SessionServiceProvider 时,我使用 SessionManager 和相同的无法解析的 $app 变量遇到了这种情况。

    在阅读了@krisanalfa 的回答后,我试图查看$availableBindings 的值,它可以在Application.php 中找到,它看起来像这样:

    public $availableBindings = [
          'auth' => 'registerAuthBindings',
          'auth.driver' => 'registerAuthBindings',
          'Illuminate\Auth\AuthManager' => 'registerAuthBindings',
    
          'Illuminate\Contracts\Cache\Factory' => 'registerCacheBindings',
          'Illuminate\Contracts\Cache\Repository' => 'registerCacheBindings',
          ....
    ];
    

    每个键的值表示将用于加载实现的方法,这些实现也在Application.php 中。

    如果需要加载配置并注册绑定:

    protected function registerAuthBindings()
    {
        $this->singleton('auth', function () {
            return $this->loadComponent('auth', 'Illuminate\Auth\AuthServiceProvider', 'auth');
        });
    
        $this->singleton('auth.driver', function () {
            return $this->loadComponent('auth', 'Illuminate\Auth\AuthServiceProvider', 'auth.driver');
        });
    
       ...
    }
    

    但是如果服务不需要任何配置,你只需像这样注册它:

    protected function registerEventBindings()
    {
        $this->singleton('events', function () {
            $this->register('Illuminate\Events\EventServiceProvider');
    
            return $this->make('events');
        });
    }
    

    撰写本文时的来源:https://github.com/laravel/lumen-framework/blob/5.8/src/Application.php

    希望这对将来的其他人有所帮助。这花了我很多时间。

    【讨论】:

      猜你喜欢
      • 2017-01-11
      • 1970-01-01
      • 1970-01-01
      • 2020-05-11
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 2023-04-10
      相关资源
      最近更新 更多