从忘记密码电子邮件链接

时间:2017-09-20 10:53:24

标签: php laravel email laravel-5 passwords

我目前正在使用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);
    }
}

1 个答案:

答案 0 :(得分:0)

以下是我自己的应用中的一个示例,我将通过以下方式与您联系:

 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()方法抛出异常,则因为在数据库中找不到令牌,或者已经过期。

$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匹配,并检查有效期是否仍在将来。如果没有,它会抛出异常,在这种情况下,您不想显示您的表单!

我希望这有助于您了解重置电子邮件流程!