如何构造Firebase auth密码重置流程?

时间:2022-04-27 20:29:27

I'm using the Firebase authentication solution for registering/logging-in users in my Ionic app. I'm struggling on how to best implement my 'password reset flow'.

我正在使用Firebase身份验证解决方案,在我的Ionic应用程序中注册/登录用户。

Currently, when a user forgets their password the flow starts as below:

目前,当用户忘记密码时,流开始如下:

html:

html:

<p class="forgot-text" ng-click="login.resetPassword()" ng-show="login.email">Forgot password?</p>

controller:

控制器:

vm.resetPassword = function() {
    authService.resetPassword(vm.email);
};

authService:

authService:

function resetPassword(email) {
    auth.$resetPassword({
        email: email
    }).then(function() {
        $location.path('/intro');
    }).catch(function(error) {
        alert(error);
    });
}

As a result of the above the user receives an email with a temporary password. Thankfully there is an isTemporaryPassword field on the authData object returned when a user logs in.

因此,用户会收到一封带有临时密码的电子邮件。值得庆幸的是,在用户登录时返回的authData对象上有一个isTemporaryPassword字段。

I take advantage of this within my authService:

我在我的工作中充分利用了这一点:

function loginUser(email, password) {
    auth.$authWithPassword({
        email: email,
        password: password
    }).then(function(authData) {
        if (authData.password.isTemporaryPassword) {
            $location.path('/reset');
        } else {
            $location.path('/people');
        }
    }).catch(function(error) {
        alert(error);
    });
}

This is where my problem arises. When the user reaches /reset I want them to simply be able to enter their new password twice (second entry for confirmation), but the Firebase $changePassword method takes not just email and new password, but also old password. This seems redundant to me as the user just entered their old (temporary) password in order to arrive at this screen. Here's changePassword from my authService:

这就是我的问题所在。当用户到达/重置时,我希望他们能够简单地输入他们的新密码两次(第二次确认),但是Firebase $changePassword方法不仅接受电子邮件和新密码,还接受旧密码。这对我来说似乎是多余的,因为用户只是输入了他们的旧(临时)密码来到达这个屏幕。以下是我的认证:

function changePassword(email, oldPassword, newPassword) {
    auth.$changePassword({
        email: email,
        oldPassword: oldPassword,
        newPassword: newPassword
    }).then(function() {
        $location.path('/people');
    }).catch(function(error) {
        alert(error);
    });
}

I could always just force the user to enter their temporary password yet again, or I could set this temporary password to $rootScope, but I feel like there must be a cleaner option. Any ideas?

我总是可以强迫用户再次输入他们的临时密码,或者我可以将这个临时密码设置为$rootScope,但是我觉得必须有一个更干净的选项。什么好主意吗?

1 个解决方案

#1


2  

I was able to solve this in a very simple manner. I changed the $location.path line in my authService $resetPassword function to the below:

我能以非常简单的方式解决这个问题。我改变了美元的位置。我的authService $resetPassword函数中的路径行到下面:

$location.path('/reset');

I then updated my reset-password.html to the following:

然后我更新了重置密码。html如下:

<ion-view view-title="Reset Password" class="login-background">

<div class="signup-form">

<div class="list list-inset signup">
  <label class="item item-input">
    <span class="input-label" style="text-align:right">Email</span>
    <input type="text" placeholder="name@example.com" ng-model="reset.email">
  </label>
  <label class="item item-input">
    <span class="input-label" style="text-align:right">Temporary Password</span>
    <input type="password" ng-model="reset.tempPassword">
  </label>
  <label class="item item-input">
    <span class="input-label" style="text-align:right">New Password</span>
    <input type="password" ng-model="reset.newPassword">
  </label>
  <label class="item item-input">
    <span class="input-label" style="text-align:right">Confirm</span>
    <input type="password" ng-model="reset.confirmedPassword">
  </label>
</div>

<button class="button button-balanced" ng-click="reset.changePassword()">Update Password</button>

<p class="mismatch" ng-show="reset.mismatch">{{ reset.mismatchMessage }}</p>

Finally, the changePassword function within my controller looks like this:

最后,我的控制器中的changePassword函数如下所示:

vm.changePassword = function() {
  vm.mismatch = false;

  if (vm.newPassword === vm.confirmedPassword) {
    authService.changePassword(vm.email, vm.tempPassword, vm.newPassword);
  } else {
    vm.mismatch = true;
    vm.mismatchMessage = 'Password and confirmation must match';
  }
};

#1


2  

I was able to solve this in a very simple manner. I changed the $location.path line in my authService $resetPassword function to the below:

我能以非常简单的方式解决这个问题。我改变了美元的位置。我的authService $resetPassword函数中的路径行到下面:

$location.path('/reset');

I then updated my reset-password.html to the following:

然后我更新了重置密码。html如下:

<ion-view view-title="Reset Password" class="login-background">

<div class="signup-form">

<div class="list list-inset signup">
  <label class="item item-input">
    <span class="input-label" style="text-align:right">Email</span>
    <input type="text" placeholder="name@example.com" ng-model="reset.email">
  </label>
  <label class="item item-input">
    <span class="input-label" style="text-align:right">Temporary Password</span>
    <input type="password" ng-model="reset.tempPassword">
  </label>
  <label class="item item-input">
    <span class="input-label" style="text-align:right">New Password</span>
    <input type="password" ng-model="reset.newPassword">
  </label>
  <label class="item item-input">
    <span class="input-label" style="text-align:right">Confirm</span>
    <input type="password" ng-model="reset.confirmedPassword">
  </label>
</div>

<button class="button button-balanced" ng-click="reset.changePassword()">Update Password</button>

<p class="mismatch" ng-show="reset.mismatch">{{ reset.mismatchMessage }}</p>

Finally, the changePassword function within my controller looks like this:

最后,我的控制器中的changePassword函数如下所示:

vm.changePassword = function() {
  vm.mismatch = false;

  if (vm.newPassword === vm.confirmedPassword) {
    authService.changePassword(vm.email, vm.tempPassword, vm.newPassword);
  } else {
    vm.mismatch = true;
    vm.mismatchMessage = 'Password and confirmation must match';
  }
};