User Model 里面的 sendPasswordResetNotification ( ) 在什么时候调用?

  1. 邮件发送重置密码的URL链接(带token)的动作是在哪一步执行的?
    根据路由, 是在 Auth\ForgotPasswordController@sendResetLinkEmail 这里执行, 但具体是怎么实现的? 虽然是Laravel早已编写好, 但实在不太理解, 是怎么生成token? 然后又是怎么把带上token的URL发送邮件出去?

  2. User Model 里面的 sendPasswordResetNotification( ) 在什么时候调用?

public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPassword($token));
    }

求大神解答~十分感谢~

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

我跟着线索找了一下,不知道对不对,sendResetLinkEmail这个方法定义在SendsPasswordResetEmails这个trait中。

public function sendResetLinkEmail(Request $request)
    {
        $response = $this->broker()->sendResetLink(
            $request->only('email')
        );
    }

在执行的过程中会调用sendResetLink()这个方法,找到在Illuminate/Auth/Passwords/PasswordBroker.php中的定义,执行过程中会又会调用:

        $user->sendPasswordResetNotification(
            $this->tokens->create($user)
        );

看看$this->tokens是怎么构造的:

public function __construct(TokenRepositoryInterface $tokens,
                                UserProvider $users)
    {
        $this->users = $users;
        $this->tokens = $tokens;
    }

可以看到传入了两个参数,其中和token有关的参数是TokenRepositoryInterface $tokens,token是通过TokenRepositoryInterface这个接口产生的,转而寻找实现这个接口的类,然后找到Illuminate/Auth/Passwords/DatabaseTokenRepository.php,其中就有create()这个方法:

 public function create(CanResetPasswordContract $user)
    {
        $email = $user->getEmailForPasswordReset();

        $this->deleteExisting($user);

        $token = $this->createNewToken();

        $this->getTable()->insert($this->getPayload($email, $token));

        return $token;
    }

就是在这里完成了token的生成,同时写入数据表,返回这个token,既然知道这个token是怎么来的了,反过来就是token出现在邮件中的过程了。
第一次用markdown,排版效果可能不理想,望谅解。

5年前 评论
讨论数量: 8

我跟着线索找了一下,不知道对不对,sendResetLinkEmail这个方法定义在SendsPasswordResetEmails这个trait中。

public function sendResetLinkEmail(Request $request)
    {
        $response = $this->broker()->sendResetLink(
            $request->only('email')
        );
    }

在执行的过程中会调用sendResetLink()这个方法,找到在Illuminate/Auth/Passwords/PasswordBroker.php中的定义,执行过程中会又会调用:

        $user->sendPasswordResetNotification(
            $this->tokens->create($user)
        );

看看$this->tokens是怎么构造的:

public function __construct(TokenRepositoryInterface $tokens,
                                UserProvider $users)
    {
        $this->users = $users;
        $this->tokens = $tokens;
    }

可以看到传入了两个参数,其中和token有关的参数是TokenRepositoryInterface $tokens,token是通过TokenRepositoryInterface这个接口产生的,转而寻找实现这个接口的类,然后找到Illuminate/Auth/Passwords/DatabaseTokenRepository.php,其中就有create()这个方法:

 public function create(CanResetPasswordContract $user)
    {
        $email = $user->getEmailForPasswordReset();

        $this->deleteExisting($user);

        $token = $this->createNewToken();

        $this->getTable()->insert($this->getPayload($email, $token));

        return $token;
    }

就是在这里完成了token的生成,同时写入数据表,返回这个token,既然知道这个token是怎么来的了,反过来就是token出现在邮件中的过程了。
第一次用markdown,排版效果可能不理想,望谅解。

5年前 评论

这个问题好像知道的人不多啊?这节看得比较迷糊

5年前 评论

sendResetLinkEmail 调用在 Illuminate\Auth\Passwords\PasswordBroker 里的 sendResetLink function , 它调用了 $user->sendPasswordResetNotification(
$this->tokens->create($user)
)。
这个调用了 Illuminate\Auth\Passwords\DatabaseTokenRepository 的create function生成 $token。
不知道对不对。

5年前 评论

我跟着线索找了一下,不知道对不对,sendResetLinkEmail这个方法定义在SendsPasswordResetEmails这个trait中。

public function sendResetLinkEmail(Request $request)
    {
        $response = $this->broker()->sendResetLink(
            $request->only('email')
        );
    }

在执行的过程中会调用sendResetLink()这个方法,找到在Illuminate/Auth/Passwords/PasswordBroker.php中的定义,执行过程中会又会调用:

        $user->sendPasswordResetNotification(
            $this->tokens->create($user)
        );

看看$this->tokens是怎么构造的:

public function __construct(TokenRepositoryInterface $tokens,
                                UserProvider $users)
    {
        $this->users = $users;
        $this->tokens = $tokens;
    }

可以看到传入了两个参数,其中和token有关的参数是TokenRepositoryInterface $tokens,token是通过TokenRepositoryInterface这个接口产生的,转而寻找实现这个接口的类,然后找到Illuminate/Auth/Passwords/DatabaseTokenRepository.php,其中就有create()这个方法:

 public function create(CanResetPasswordContract $user)
    {
        $email = $user->getEmailForPasswordReset();

        $this->deleteExisting($user);

        $token = $this->createNewToken();

        $this->getTable()->insert($this->getPayload($email, $token));

        return $token;
    }

就是在这里完成了token的生成,同时写入数据表,返回这个token,既然知道这个token是怎么来的了,反过来就是token出现在邮件中的过程了。
第一次用markdown,排版效果可能不理想,望谅解。

5年前 评论

@doderic 感谢感谢~也感谢各位大神的耐心讲解~

5年前 评论

@doderic 大神,还想了解一下,我看这个过程中并没有把表名传进去,DatabaseTokenRepository.php的__construct方法是怎么得到$table,把token存入到数据库的password_reset表里的呢?

5年前 评论

@XISHAN 追源码好累 :dizzy_face: ,DatabaseTokenRepository 的参数是在 Illuminate/Auth/Passwords/PasswordBrokerManager.php 中传入的:

protected function createTokenRepository(array $config)
{
    ...
    return new DatabaseTokenRepository(
        $this->app['db']->connection($connection),
        $this->app['hash'],
        $config['table'],
        $key,
        $config['expire']
    );
}

各个参数的构建方法也在这个类中,具体的过程可以自己试着去看,去理解;单就 $table 来说,是把 config/auth.php 中定义的表名传递到 DatabaseTokenRepository 的实例中。

passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'password_resets',    // 定义的表名
        'expire' => 60,
    ],
],
5年前 评论

@doderic 感谢您的讲解,之前没有看文档的契约这一章,对于如何通过interface追寻源码不太了解,看过之后自己能找到了,不过这里我还是不太明白为什么调用DatabaseTokenRepository.php的create方法,是在PasswordBrokerManager.php的createTokenRepository方法里实例化的。新手上路,请多包涵- -
file

5年前 评论

@XISHAN 我也是新手,共同进步。

回到 Illuminate\Foundation\Auth\SendsPasswordResetEmails.php 这个 trait ,此处有个 broker 方法:

public function sendResetLinkEmail(Request $request)
{
    $response = $this->broker()->sendResetLink(
        $request->only('email')
    );
}

方法的定义:

/**
* Get the broker to be used during password reset.
*
* @return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
    return Password::broker();
}

注意看注释,而后是 Illuminate/Auth/Passwords/PasswordBrokerManager.php,再看注释

/**
 * @mixin \Illuminate\Contracts\Auth\PasswordBroker
 */
class PasswordBrokerManager implements FactoryContract
{
    ...
}
5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!