【问题标题】:User repository class as user provider and dependency injection用户存储库类作为用户提供者和依赖注入
【发布时间】:2014-05-01 18:46:44
【问题描述】:

我正在关注tutorial(如何使用 API 密钥验证用户)在我的应用程序中实现 api 密钥。

我正在使用基于此tutorial(如何从数据库加载安全用户)创建的用户存储库类作为预身份验证过程中所需的用户提供程序,因为该类已经具有方法在我正在关注的教程中描述为用户提供者的需要,即loadUserByUsername()refreshUser()supportsClass()

Symfony 调用我的apikey_authenticator 服务,它需要一个用户提供者作为参数。因此,我配置了另一个名为 userprovider 的服务,这是我的用户存储库类,如下所示:

services:
apikey_authenticator:
    class: MyBundle\Security\ApiKeyAuthenticator
    arguments: ["@userprovider"]
userprovider:
    class: MyBundle\Entity\UserRepository

但我的用户存储库类依赖于实体管理器,我不知道如何注入。我的学说的配置是symfony自带的默认配置:

# Doctrine Configuration
doctrine:
dbal:
    driver:   "%database_driver%"
    host:     "%database_host%"
    port:     "%database_port%"
    dbname:   "%database_name%"
    user:     "%database_user%"
    password: "%database_password%"
    charset:  UTF8

orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    auto_mapping: true

我该如何解决这个问题?在这种情况下,使用用户存储库类作为用户提供者是否是个好主意?

【问题讨论】:

    标签: php symfony dependency-injection doctrine-orm api-key


    【解决方案1】:

    Doctrine 实体存储库是使用工厂创建的。这是一个例子:

    cerad_game__game_repository__doctrine:
        class:  Cerad\Bundle\GameBundle\Doctrine\EntityRepository\GameRepository
        factory_service: 'doctrine.orm.default_entity_manager'
        factory_method:  'getRepository'
        arguments:  
            - 'Cerad\Bundle\GameBundle\Doctrine\Entity\Game'
    

    这是个好主意吗?将存储库注入 UserProvider 类可能会更干净,而不是使用 UserProvider 方法将存储库弄乱。但无论哪种方式都可以。

    【讨论】:

      【解决方案2】:

      只是想添加我的 2c,因为我也遵循了你提到的那些指南。

      我已经定义了一个 Authenticator 和 provider 类。身份验证器只进行必要的安全检查,提供者处理数据库连接(例如通过令牌返回用户)。

      在我的提供者的 __construct 中,我有这个:

      protected $em;
      protected $repositoryClass = 'myrepoclass';
      protected $repository;
      
      public function __construct(EntityManager $em) {
          $this->em = $em;
          $this->repository = $this->em->getRepository($this->repositoryClass);
      }
      

      现在我可以调用像 $this->repository->findOneById($id); 这样的查询。 我明确定义了存储库类,因为它允许在我认为需要时更轻松地切换到其他实体(当然可能是错误的想法)。

      在我的服务文件中,我有这个:

      api_user_provider:
        class: "%api_user_provider.class%"
        arguments: ["@doctrine.orm.entity_manager"]
      
      api_user_authenticator:
        class: "%api_user_authenticator.class%"
        arguments: ["@api_user_provider"]
      

      提供者类与实体类不同(至少对我而言)。我把它们分开了,因为我认为这样更干净。

      嗯,我就是这样设置的。希望这会有所帮助:)

      编辑:由于我创建了一个单独的包(ApiBundle 和 UserBundle),我将提供程序与实体类分开。我还遵循了“从数据库加载安全用户”教程,这是我实现 API 令牌身份验证的最后一件事。尽管您的存储库中已经有相同的方法,但我仍然认为最好像我一样将它与存储库类分开(这当然取决于您的需要),因为我认为这样更干净。当然,决定权取决于您要做什么:)

      【讨论】:

      • 直接注入存储库而不是实体管理器可能更干净。有关如何配置存储库服务的示例,请参阅我的答案。
      猜你喜欢
      • 2021-04-23
      • 2012-09-21
      • 2016-08-31
      • 1970-01-01
      • 2018-08-21
      • 2018-05-02
      • 2021-02-18
      • 1970-01-01
      • 2014-10-28
      相关资源
      最近更新 更多