通过电子邮件或手机在Laravel 5.5中重置密码 [英] Password reset in Laravel 5.5 by email or mobile

查看:159
本文介绍了通过电子邮件或手机在Laravel 5.5中重置密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

默认情况下,Laravel 5.5的密码重置系统适用于电子邮件,但是我需要添加对手机号码的支持(通过OTP验证并生成令牌并重定向到密码重置页面).我正在做所有这部分,并在password_resets表上创建了一个移动列.

By default Laravel 5.5's password reset system works on email, but I need to add support for a mobile number (verify by OTP and generate a token and redirect to password reset page). I am doing all this part and I have created a mobile column on password_resets table.

但问题是\Illuminate\Auth\Passwords\DatabaseTokenRepository&& \Illuminate\Auth\Passwords\TokenRepositoryInterface ON exist方法,它似乎不可配置.

But the problem is \Illuminate\Auth\Passwords\DatabaseTokenRepository && \Illuminate\Auth\Passwords\TokenRepositoryInterface ON exist method and it doesn't seem configurable.

public function exists(CanResetPasswordContract $user, $token)
{
    $record = (array) $this->getTable()->where(
        'email', $user->getEmailForPasswordReset()
    )->first();

    return $record &&
           ! $this->tokenExpired($record['created_at']) &&
             $this->hasher->check($token, $record['token']);
}

我需要重写该方法.继承如此之多. 我需要扩展哪些类以及如何覆盖该方法.

I need to override that method. There's so much inheritance going on. What classes do I need to extend and how to override that method.

推荐答案

如果要覆盖\Illuminate\Auth\Passwords\DatabaseTokenRepository方法的行为,则必须覆盖所有引用电子邮件"列的方法.创建这些文件:

If you want to override behaviour of \Illuminate\Auth\Passwords\DatabaseTokenRepository methods, you will have to override every method that references "email" column. Create these files:

/App/Auth/DatabaseTokenRepository.php

<?php

namespace App\Auth;

use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Auth\Passwords\DatabaseTokenRepository as DatabaseTokenRepositoryBase;

class DatabaseTokenRepository extends DatabaseTokenRepositoryBase
{

    public function create(CanResetPasswordContract $user)
    {
        $email = $user->getEmailForPasswordReset();
        $mobile = $user->getMobileForPasswordReset();
        $this->deleteExisting($user);
        $token = $this->createNewToken();
        $this->getTable()->insert($this->getPayload($email, $mobile, $token));
        return $token;
    }

    protected function deleteExisting(CanResetPasswordContract $user)
    {
        return $this->getTable()
            ->where('email', $user->getEmailForPasswordReset())
            ->orWhere("mobile", $user->getMobileForPasswordReset())
            ->delete();
    }

    protected function getPayload($email, $mobile, $token)
    {
        return ['email' => $email, 'mobile' => $mobile, 'token' => $this->hasher->make($token), 'created_at' => new Carbon];
    }

    public function exists(CanResetPasswordContract $user, $token)
    {
        $record = (array) $this->getTable()
            ->where('email', $user->getEmailForPasswordReset())
            ->orWhere("mobile", $user->getMobileForPasswordReset())
            ->first();
        return $record &&
               ! $this->tokenExpired($record['created_at']) &&
                 $this->hasher->check($token, $record['token']);
    }
}

现在,您将需要使用此自定义令牌存储库,而不是默认存储库.因此,您必须重写另一个类.

Now you will need to use this custom token repository instead of the default one. So you have to override another class.

/App/Auth/PasswordBrokerManager.php

<?php
namespace App\Auth;

use Illuminate\Support\Str;
use Illuminate\Auth\Passwords\PasswordBrokerManager as PasswordBrokerManagerBase;

class PasswordBrokerManager extends PasswordBrokerManagerBase
{

    protected function createTokenRepository(array $config)
    {
        $key = $this->app['config']['app.key'];
        if (Str::startsWith($key, 'base64:')) {
            $key = base64_decode(substr($key, 7));
        }
        $connection = $config['connection'] ?? null;
        return new DatabaseTokenRepository(
            $this->app['db']->connection($connection),
            $this->app['hash'],
            $config['table'],
            $key,
            $config['expire']
        );
    }
}

现在,您已经创建了一个自定义代理以使用您的自定义存储库.您需要一个新的服务提供商才能使用它.

Now you have created a custom broker to use your custom repository. You need a new service provider to make use of it.

/App/Providers/PasswordResetServiceProvider.php

<?php
namespace App\Providers;

use App\Auth\PasswordBrokerManager;
use Illuminate\Auth\Passwords\PasswordResetServiceProvider as PasswordResetServiceProviderBase;

class PasswordResetServiceProvider extends PasswordResetServiceProviderBase
{
    protected function registerPasswordBroker()
    {
        $this->app->singleton('auth.password', function ($app) {
            return new PasswordBrokerManager($app);
        });
        $this->app->bind('auth.password.broker', function ($app) {
            return $app->make('auth.password')->broker();
        });
    }
}

然后只需将默认密码重置服务提供商替换为应用程序配置中的自定义密码提供商即可.

Then just replace default password reset service provider with the custom one in your application config.

这篇关于通过电子邮件或手机在Laravel 5.5中重置密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆