【问题标题】:Validate token after redirection from forgot password email link从忘记密码电子邮件链接重定向后验证令牌
【发布时间】:2018-03-01 09:37:46
【问题描述】:

我目前正在开发 Laravel 5.5 中的 forgot 密码 API 和 reset 密码 API。目前,我不知道如何在单击电子邮件中的链接并显示重置密码确认密码后验证密码。

我已将令牌与电子邮件一起发送。问题是在询问密码和确认密码之前,我需要先验证令牌是否是表中的有效令牌及其到期日期。谁能指导我如何做到这一点?

这是我忘记的密码。

public function forgotPasswordApi(Request $request){
    $rawPostData = json_decode($request->getContent(), true);

    if(isset($rawPostData['email'])) {
        $user = UserModel::where('email',$rawPostData['email'])->first();
        $token=TokenModel::where('user_id',$user->id)->first();
        if($user){
            if(!$token){
                $token=new TokenModel;
                $token->token=md5(uniqid().$token->id);
                $token->token_code = TokenModel::$forgotPasswordToken;
                $token->expire_date = date("F j, Y, H:i:s", strtotime('+24 hour'));
                $token->user_id=$user->id;
                $token->save();
            }
            Mail::raw($user, function ($message) use ($user){
                 $token=TokenModel::where('user_id',$user->id)->first();
                 $message->to($user['email'])
                 ->subject('Forgot Password Subject')
                 ->setBody('To reset password. Click on the following URL. '.url('/password/reset/?token=').$token->token);
            });
        }
        $data['status'] = 'success';
        $data['msg'] = $token;
    }else{
        $data['status']='fail';
        $data['msg']='Missing required paramater';
    }
    return new JsonResponse($data);
}

注意:带有重置链接的邮件已成功发送,但我不知道通过该链接重置密码。

电子邮件示例

To reset password. Click on the following URL.
 http://127.0.0.1:8000/password/reset?token=fca709c8a8ef5ff61aa5bb73e475c602

这是我的不完整的重置密码

    public function resetPasswordApi(Request $request){

    if(Input::has('token'))
    {
        $token_input = Input::get('token');

        $token = DB::tables('tokens')
        ->where('token',$token_input)
        ->where('expire_date','>=',Carbon::now()->subHours(12))
        ->first();
    }else{
        dd('input value not found');
    }


    $rawPostData = json_decode($request->getContent(), true);
    if($token)
    {
        if(isset($rawPostData['password'],$rawPostData['confirm_password']))
        {
            if($rawPostData['password'] === $rawPostData['confirm_password'])
            {
                $updatedUser = UserModel::where('id',$token->user_id)->first();
                $updatedUser->password = bcrypt($rawPostData['password']);
                $updatedUser->save();

                $data['status'] = 'success';
            }
            else
            {
                $data['status']='fail';
                $data['msg']='Password and Confirm Password Match failed.';
            }
         }
         else
         {
            $data['status']='fail';
            $data['msg']='Missing required paramater';
         }
    }
    else
    {
        $data['status']='fail';
        $data['msg']='Missing required paramater';
    }
      return new JsonResponse($data);
    }
}

【问题讨论】:

标签: php laravel email laravel-5 passwords


【解决方案1】:

这是我自己的一个应用程序中的一个示例,我会告诉你:

 public function resetPassAction()
    {
        $email = $this->_request->getParam('email');
        $token = $this->_request->getParam('token');

        $user = $this->getUserService()->findUserByEmail($email);
        if (!$user) {
            throw new Zend_Controller_Action_Exception(UserException::USER_NOT_FOUND);
        }

        try {
            $link = $this->getUserService()->findEmailLink($email, $token);
        } catch (EmailLinkException $e) {
            $this->view->message = [$e->getMessage(), 'danger'];
            return;
        } catch (Exception $e) {
            throw $e;
        }

        $form = new Application_Form_ResetPass();


        if ($this->getRequest()->isPost()) {

            $data = $this->getRequest()->getParams();

            if ($form->isValid($data)) {

                if ($data['password'] == $data['confirm']) {
                    $this->getUserService()->changePassword($user, $data['password']);
                    $this->getUserService()->deleteEmailLink($link);
                    $this->view->message = [' You have successfully changed your password.', 'success'];
                    $this->view->success = true;
                } else {
                    $this->view->message = $this->view->message = ['Passwords did not match, please try again.', 'danger'];
                    $this->view->form = $form;
                }
            } else {
                $this->view->form = $form;
            }
        } else {
            $this->view->form = $form;
        }

所以我们从 GET 查询中获取电子邮件地址和令牌,然后在数据库中找到用户。

然后我们找到“电子邮件链接”。这只是包含用户 ID、令牌字符串和到期日期的一行。如果findEmailLink()方法抛出异常,那是因为在db中找不到token,或者已经过期了。

$form = //etc 行中的代码是实际更改密码的代码,您不必担心。

这是实际的 findEmailLink() 代码:

public function findEmailLink($email, $token)
    {
        $link = $this->getEmailLinkRepository()->findByToken($token);
        if(!$link) {
            throw new EmailLinkException(EmailLinkException::LINK_NOT_FOUND);
        }
        if($link->getUser()->getEmail() != $email) {
            throw new EmailLinkException(EmailLinkException::LINK_NO_MATCH);
        }
        if($link->getExpiryDate() < new DateTime()) {
            throw new EmailLinkException(EmailLinkException::LINK_EXPIRED);
        }
        return $link;
    }

所有这一切都是获取它,检查它是否与用户的 ID 匹配,并检查到期日期是否还在未来。如果不是,它会抛出异常,在这种情况下你不想显示你的表单!

我希望这可以帮助您了解重置电子邮件流程!

【讨论】:

    猜你喜欢
    • 2018-08-17
    • 2020-11-01
    • 2021-10-09
    • 2017-11-12
    • 2021-02-28
    • 2013-11-14
    • 2013-06-24
    • 1970-01-01
    • 2016-08-31
    相关资源
    最近更新 更多