Forgot password flow
See original GitHub issueI’m trying to set up the “forgot password flow”. In my Rails 5 backend I’m using devise_token_auth (0.1.40).
I set the frontend up as in the documentation, meaning when an user requests a new password, I call:
this._tokenService.resetPassword({
email: this.resetPasswordForm.value.email,
});
This works as intended, and the backend sends an e-mail to the user with a token.
However, when the user clicks the link, and the password reset form is I call this:
this._tokenService.updatePassword({
password: this.resetPasswordForm.value.password,
passwordConfirmation: this.resetPasswordForm.value.password_confirmation,
passwordCurrent: null,
resetPasswordToken: this.resetPasswordForm.value.password_token
});
I now see a call happening to /auth with the provided data which fails with error “User not found”. In my Rails log, I see this:
| Started PUT “//auth” for ::1 at 2017-04-02 14:23:03 +0200 | Processing by DeviseTokenAuth::RegistrationsController#update as JSON | Parameters: {“password”=>“[FILTERED]”, “password_confirmation”=>“[FILTERED]”, “reset_password_token”=>“[FILTERED]”, “registration”=>{“password”=>“[FILTERED]”, “password_confirmation”=>“[FILTERED]”, “reset_password_token”=>“[FILTERED]”}} | Unpermitted parameters: reset_password_token, registration
It seems that the password, password_confirmation and reset_password_token are being sent, and somewhere being re-routed/copied into registration: { password, password_confirmation, reset_password_token}.
I’ve looked into the source code of devise_token_auth, and noticed that the flow of reset password might be different than you expect. It seems you need an extra call, to allow a user-object to change the password once without a “current password”. The ‘def edit’ in the PasswordController of devise_token_auth states:
this is where users arrive after visiting the password reset confirmation link
So, it seems like when you open the form, you have to make a call to tell the backend an user has visited the form with the reset-token. https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/controllers/devise_token_auth/passwords_controller.rb#L94 There it seems like the user-permissions is set to change the password once, basically setting up the User model to expect an incoming password change.
Any ideas? If you require additional information, I’d be happy to help.
Issue Analytics
- State:
- Created 6 years ago
- Comments:17 (11 by maintainers)
Top GitHub Comments
Thanks @cybey, I ended up using another somewhat hacky approach and just sidestepped devise altogether. Basically, I generate a link with a password reset token and just search my users by that token when the user comes back, update the user with the password/password_confirmation provided by the client, return a 200 then login from the client using the newly set password and _tokenService.signIn(). Not the best but it seems to be the simplest for my purposes.
Thanks for the help!
I’m in the process of looking at this very issue. I don’t think it needs that magic on the server side. The current process effectively logs in the user when they click on the email link (you can test this by pasting in a protected URL at that point). The password reset page response from the server after clicking the email link includes a new valid access code. The problem is that the actual call to edit the password doesn’t have this code in it (instead it repeats the reset token, which will actually work if you set your “burst” time setting on the server to something long enough to allow you to get the new password in before it expires). So it’s a one line fix I think. I’m currently fighting with the structure of this lib trying to set up a test of that one line, but I think I have figured that out, so should have a pr by tomorrow (big sports game in Dublin today! )