通过电子邮件或手机在 Laravel 中重置密码

2024-02-21

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

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

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']);
}

我需要重写该方法。有太多的遗产正在发生。 我需要扩展哪些类以及如何重写该方法。


如果你想覆盖的行为\Illuminate\Auth\Passwords\DatabaseTokenRepository方法,您将必须构建自己的令牌存储库,覆盖现有存储库中当前仅检查数据库中的“电子邮件”列的方法。确保您已创建迁移以添加适当的列:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        $tname = config("auth.passwords.users.table");
        Schema::table($tname, fn (Blueprint $t) => $t->string("mobile", 16));
    }

    public function down(): void
    {
        $tname = config("auth.passwords.users.table");
        Schema::table($tname, fn (Blueprint $t) => $t->dropColumn("mobile"));
    }
}

然后创建您的自定义存储库:

应用程序/Auth/DatabaseTokenRepository.php

<?php

namespace App\Auth;

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

class DatabaseTokenRepository extends DatabaseTokenRepositoryBase;
{
    //
    // Override these methods to use mobile as well as email
    //
    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): array
    {
        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"]);
    }

    public function recentlyCreatedToken(CanResetPasswordContract $user)
    {
        $record = (array) $this->getTable()
            ->where("email", $user->getEmailForPasswordReset())
            ->orWhere("mobile", $user->getMobileForPasswordReset())
            ->first();

        return $record && $this->tokenRecentlyCreated($record['created_at']);
    }
}

现在您需要使用此自定义令牌存储库而不是默认令牌存储库。所以你必须重写另一个类。

应用程序/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 an instance of your new repository
        // it's in the same namespace, no need to alias it
        return new DatabaseTokenRepository(
            $this->app['db']->connection($connection),
            $this->app['hash'],
            $config['table'],
            $key,
            $config['expire']
        );
    }
}

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

应用程序/提供商/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) {
            // reference your new broker
            // the rest of the method code is unchanged
            return new PasswordBrokerManager($app);
        });
        $this->app->bind('auth.password.broker', function ($app) {
            return $app->make('auth.password')->broker();
        });
    }
}

接下来,将默认密码重置服务提供商替换为应用程序配置中的自定义提供商:应用程序/配置/app.php

<?php

return [
    "providers" => [
        ...
        // Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        App\Providers\PasswordResetServiceProvider::class,
        ...
    ],
];

最后,定义getMobileForPasswordReset()您的用户模型上的方法:

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
...

class User extends Authenticatable
{
    ...
    public method getMobileForPasswordReset()
    {
        return $this->mobile;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过电子邮件或手机在 Laravel 中重置密码 的相关文章

随机推荐

  • 调用 SaveChanges() 时排除更新属性

    似乎有两种方法可以使用 附加 方法来更新断开连接的实体框架实体 方法一是简单地将断开连接的实体的状态设置为已修改 myDbContext Dogs Attach dog myDbContext Entry dog State EntityS
  • 如何在C#中枚举音频输出设备

    我想知道如何获取计算机上已安装的音频输出设备 waveOut 的列表 操作系统 Windows XP Vista 7 框架 Net 3 5 语言 c 迭代此列表时 我想获取每个设备的标识符 制造商等信息 有什么提示吗 下面是使用 WMI 参
  • JSP 组件创建

    创建 JSP 页面时 我经常喜欢的一件事是能够执行以下操作
  • Gulp 伊斯坦布尔完整覆盖报告

    我正在使用 gulp istanbul 通过 Gulp 生成 JavaScript 单元测试覆盖率报告 有没有办法配置 Istanbul 以生成我的 gulp 流中所有 JS 文件的完整覆盖率报告 而不仅仅是测试用例涉及的文件 我正在开发一
  • main 函数不返回任何内容。为什么? [复制]

    这个问题在这里已经有答案了 对于 C C main 必须始终返回一个整数 零表示成功 非零表示失败 我可以理解这一点 因为程序运行时它成为一个进程 每个进程都应该有一个退出状态 我们通过执行 echo 获得退出状态 进程结束后从 shell
  • 如何在 git 中找到 origin/master 的位置,以及如何更改它?

    我是 Git 新手 我最近将一个 Rails 项目从 Subversion 迁移到了 Git 我按照这里的教程进行操作 http www simplisticcomplexity com 2008 03 05 cleanly migrate
  • 如何创建像所附照片一样的用户界面

    谁能告诉我这个照片效果叫什么 我想知道如何为这个附加的图像效果创建一个适配器 编辑 这是Android市场的示例照片 我想创建一个这样的布局 我想这应该覆盖 GridView 适配器 肖像截图 风景截图 另一张截图 我非常抱歉我的问题对你们
  • 如何使用 Google Colab 安装 vizdoom?

    我正在关注本教程 https github com simoninithomas Deep reinforcement learning Course blob master Policy 20Gradients Doom Doom 20R
  • Matlab 箱线图属性

    I m trying to plot this box plot like this 我尝试了这段代码 boxplot randn 10 98 notch on set 0 DefaultAxesFontName Cambria Math
  • Heroku Rails Net::HTTP: OpenSSL::SSL::SSLError: SSL_connect 返回=1 errno=0 状态=SSLv3 读取服务器证书 B: 证书验证失败

    我有一个在 Heroku 服务器上运行的 Rails 应用程序 但我在使用 Net HTTP over HTTPS 与外部服务器通信时遇到问题 每当我尝试时收到的错误POST通过 HTTPS 到外部专有 API 的方法是 OpenSSL S
  • 为什么我的小型大写字体变体 CSS 类被忽略?

    我添加了这个 CSS 类 beanies font variant small caps 我从几个地方调用它 再加上另一个类 以这种方式尝试 p class coolPools beanies LICENSE 764014 p 和这个 h3
  • 列数会影响MYSQL的速度吗?

    我有一张桌子 我只需要运行一种类型的查询 在第 1 列中查找给定的唯一值 然后获取前 3 列 现在 如果我在表中添加额外的几列以进行基本的 数据存储 会对速度产生多大影响 我知道我应该使用一个单独的表 但假设我仅限于只有 1 个表 所以唯一
  • 将 MapReduce 作业的输出记录到文本文件

    我一直在使用这个 jobclient monitorandprintjob 方法将映射缩减作业的输出打印到控制台 我的用法是这样的 job client monitorAndPrintJob job conf job client getJ
  • python 通过通配符复制文件

    我正在学习 python python 3 我可以将 1 个文件复制到新目录 通过做这个 import shutil shutil copyfile C test test txt C lol test txt 我现在想做的是将所有 txt
  • Elixir:修改模块属性值

    是否有可能实现以下行为 其中尝试更改模块属性的值以改变模块方法的行为 defmodule Adder do num to add 10 def addTo input do input num to add end IO inspect A
  • 重新签署包含框架的 IPA

    我正在重新签名 iOS 应用程序 使用 iResign 以便将其上传到 App Store 作为其中的一部分 我正在更改捆绑包 ID 我只有 IPA 没有源代码 该应用程序包含第三方框架 辞职似乎进展顺利 但是当我使用应用程序加载器上传时
  • application.properties中的spring boot .env变量

    我已经创建了 env 文件 我现在在其中保存变量 我希望它们在我的 application properties 中定义 但这不起作用 我需要添加什么来获取变量 env 文件 MYSQLDB USER root MYSQLDB ROOT P
  • TopoJSON 属性保留

    我正在使用 topojson 转换现有的 GeoJSON 数据集 但它不保留属性 它遵循标准 GeoJSON 格式 并将属性放置在与几何图形同一级别的 属性 对象中 下面的片段 但是当 topojson 成功完成时 我最终会得到一个可以使用
  • 在两个逻辑 CPU 之间共享 TLB 条目 (Intel)

    我想知道当属于同一程序且具有相同PCID的两个线程被安排在同一物理CPU上运行时是否可以共享TLB条目 我已经研究过SDM https www intel com content www us en developer articles t
  • 通过电子邮件或手机在 Laravel 中重置密码

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