【问题标题】:How to override reset and validatePasswordWithDefaults in PasswordBroker Laravel 5如何在 PasswordBroker Laravel 5 中覆盖 reset 和 validatePasswordWithDefaults
【发布时间】:2015-07-29 05:18:05
【问题描述】:

我对这个框架真的很陌生,它对我来说似乎很神奇。 我什至找不到它在路由和控制器中调用函数 reset() 的位置。 但我知道在谷歌浏览了一整天之后,它已经在控制器之前被调用了。

问题来了, 我一直在测试在 PasswordBroker 中覆盖函数重置和函数 validatePasswordWithDefaults

我通过扩展 PasswordBroker 来做到这一点,但似乎我必须将 Illuminate\Auth\Passwords\PasswordBroker 中的所有功能完全迁移到我的 App\Services\PasswordBroker 否则我会遇到错误:

Target [Illuminate\Contracts\Auth\UserProvider] is not instantiable

我的示例代码在这里:

将我的 PasswordBroker 绑定到 Illuminate PasswordBroker 的自定义 PasswordServiceProvider:

<?php namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class PasswordResetServiceProvider extends ServiceProvider {

/**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{
    //
}

/**
 * Register the application services.
 *
 * @return void
 */
public function register()
{
    //
    $this->app->bind(
        'Illuminate\Contracts\Auth\PasswordBroker','App\Services\PasswordBroker'
        );


}

}

Custom PasswordBroker:
<?php
    namespace App\Services;


    use Illuminate\Contracts\Auth\UserProvider;
    use Illuminate\Auth\Passwords\TokenRepositoryInterface;
    use Illuminate\Auth\Passwords\PasswordBroker as BasePasswordBroker;
    use Illuminate\Contracts\Auth\PasswordBroker as ContractPasswordBroker;

    use Closure;

    class PasswordBroker extends BasePasswordBroker
    {

        public function reset(array $credentials, Closure $callback)
        {
            dd($callback);
            $user = $this->validateReset($credentials);

            if ( ! $user instanceof CanResetPasswordContract)
            {
                return $user;
            }

            $pass = $credentials['password'];

            call_user_func($callback, $user, $pass);

            $this->tokens->delete($credentials['token']);

            return PasswordBrokerContract::PASSWORD_RESET;
        }

        protected function validatePasswordWithDefaults(array $credentials)
        {
            list($password, $confirm) = [
                $credentials['password'], $credentials['password_confirmation'],
            ];

            return $password === $confirm && mb_strlen($password) >= 4;
        }
    }
    ?>

【问题讨论】:

    标签: php laravel overriding laravel-5


    【解决方案1】:

    这并不简单,我认为框架不应该将电子邮件发送到代码中,并提供一种从控制器覆盖它的方法。

    我必须覆盖电子邮件发送,因为我需要使用 Mandrill 的 api,所以我必须在邮件发送的那一刻发送额外的标题。这就是我所做的:

    1. 在 App\Providers\PasswordResetServiceProvider 上创建一个提供程序类。我复制了框架的默认提供程序(Illuminate\Auth\Passwords\PasswordResetServiceProvider),但我必须对注册顺序以及稍后检索令牌服务的方式进行一些细微的修改。您还必须指定您的 PasswordBroker 在哪里(在我的情况下是在 \App\Services\PasswordBroker 上)

       use Illuminate\Support\ServiceProvider;
       use Illuminate\Auth\Passwords\DatabaseTokenRepository as DbRepository;
      
       class PasswordResetServiceProvider extends ServiceProvider {
      
      /**
       * Indicates if loading of the provider is deferred.
       *
       * @var bool
       */
      protected $defer = true;
      
      /**
       * Register the service provider.
       *
       * @return void
       */
      public function register()
      {
          $this->registerTokenRepository();
          $this->registerPasswordBroker();
      }
      
      /**
       * Register the password broker instance.
       *
       * @return void
       */
      protected function registerPasswordBroker()
      {
          return $this->app->singleton('auth.password', function($app)
          {
              // The password token repository is responsible for storing the email addresses
              // and password reset tokens. It will be used to verify the tokens are valid
              // for the given e-mail addresses. We will resolve an implementation here.
              $tokens = $app['auth.password.tokens'];
      
              $users = $app['auth']->driver()->getProvider();
      
              $view = $app['config']['auth.password.email'];
      
              // The password broker uses a token repository to validate tokens and send user
              // password e-mails, as well as validating that password reset process as an
              // aggregate service of sorts providing a convenient interface for resets.
              return new \App\Services\PasswordBroker(
                  $tokens, $users, $app['mailer'], $view
              );
          });
      }
      
      /**
       * Register the token repository implementation.
       *
       * @return void
       */
      protected function registerTokenRepository()
      {
          $this->app->singleton('auth.password.tokens', function($app)
          {
              $connection = $app['db']->connection();
      
              // The database token repository is an implementation of the token repository
              // interface, and is responsible for the actual storing of auth tokens and
              // their e-mail addresses. We will inject this table and hash key to it.
              $table = $app['config']['auth.password.table'];
      
              $key = $app['config']['app.key'];
      
              $expire = $app['config']->get('auth.password.expire', 60);
      
              return new DbRepository($connection, $table, $key, $expire);
          });
      }
      
      /**
       * Get the services provided by the provider.
       *
       * @return array
       */
      public function provides()
      {
          return ['auth.password', 'auth.password.tokens'];
      }
      

      }

      1. 创建类\App\Services\PasswordBroker,在那里你可以覆盖emailResetLink(),这一步并不神秘。

      2. 在 config\app.php (App\Providers\PasswordResetServiceProvider) 的 providers 数组上注册新的提供者。注释掉默认的(Illuminate\Auth\Passwords\PasswordResetServiceProvider)

    【讨论】:

    • Laravel 内置了对 mandrill 的支持,为什么你必须更改那部分代码才能使用他们的 API?
    • 因为我必须在消息中发送额外的标题才能使用 Mandrill 的模板系统,例如: $headers->addTextHeader('X-MC-MergeLanguage', 'Handlebars');我检查了 mailchimp 驱动程序,它似乎不支持这些配置。您认为有更好的解决方案吗?
    • 最后我发现不用laravel的接口直接使用mandrills api更简单。
    • Mandrill 将关闭并成为 Mailchimp 的插件,我认为使用它不是一个好主意。您不想过度依赖外部服务。
    • 是的,我昨天才听说,我还不知道 laravel wrapper 的接口更新。
    猜你喜欢
    • 2016-07-17
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2015-08-09
    • 1970-01-01
    • 2015-08-11
    • 2015-07-04
    相关资源
    最近更新 更多