I am trying to reset a members password.
I want to send a token to the member and have him click a link.
When I try to reset a password I get an error that the token is invalid.
I have tried to bypass all the mail stuff but to no avail.
Example:
var member = await _memberManager.FindByEmailAsync("[email protected]");
string token = await _memberManager.GenerateEmailConfirmationTokenAsync(member);
string res = await _memberManager.ChangePasswordWithResetAsync(member.Id.ToString(), token, "1qaz2!wsx3dc");
I have also tried this variant:
var member = await _memberManager.FindByEmailAsync("[email protected]");
string token = await _memberManager.GenerateEmailConfirmationTokenAsync(member);
var test = _memberManager.ResetPasswordAsync(member, token, requestNewPassword.Password);
Have you manually created a flow that sends a token and validates the send token?
I'm not sure what your problem is since you did not add any additional information. But what I do know is that by default the password reset functionality won't work unless you set a value in the web.config.
Have you set an UmbracoMembershipProvider in the web.config?
The value allowManuallyChangingPassword must be set to true.
Thank you for showing me that configuration.
It did not help med though.
I have found a workaround using the PasswordChanger class.
I have to compare the token before changing password
var changingPasswordModel = new Umbraco.Cms.Core.Models.ChangingPasswordModel()
{
Id = id,
NewPassword = requestNewPassword.Password,
OldPassword = null
};
var changePasswordResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _memberManager);
var token = await _memberManager.GeneratePasswordResetTokenAsync(user);
var encodedToken = !string.IsNullOrEmpty(token) ? HttpUtility.UrlEncode(token) : string.Empty;
The password reset token generator is probably what you are after. Additionally, you will need to encode the token so it survives the trip back to your change password page. For some reason, the token does not get generated as encoded. Note that you probably don't have to decode it again on the way back in. Hope that helps...
Glad to hear that worked. If you are using your test scenario above where you are immediately testing the validity of the token without leaving your class, you would not need to encode it, but if you are sending the token out via email and returning it via a URL to a browser, you probably will need to encode it. If that helped you and this worked, can you please mark this one as solved?
It works as expected when using GeneratePasswordResetTokenAsync() though.
Later a new password if set from previous generated token.
var memberIdentity = await _memberManager.FindByIdAsync(model.UserId);
var result = await _memberManager.ChangePasswordWithResetAsync(memberIdentity.Id, token, model.Password);
This definitely works for members. Make sure you encode the token in the email outbound. But don’t unencode the token on the way back in. For some reason you don’t need to unencode it.
But email confirmation tokens are for validating/ confirming email addresses, not for resetting passwords. Two different methods for different purposes. For example after a member registers you want to check if there email is legit, you send them an email confirmation token. On the way back in you set email confirmed = true. Then you can test against that and approve their account at that point. Sorry I am on mobile but can post some examples later.
@bjarne When you fetch the member to change the password later using ChangePasswordWithResetAsync, I assume the inviteToken containing the member id at the start (before the | prefix) is used.
What prevents someone from changing that id number in the URL and using the link to reset someone elses password?
@Gareth, The token that is generated by GeneratePasswordResetTokenAsync() is unique to that user. If a different id or email is used against that token, the change password operations will fail.
Reset Member Password
I am trying to reset a members password. I want to send a token to the member and have him click a link. When I try to reset a password I get an error that the token is invalid. I have tried to bypass all the mail stuff but to no avail.
Example:
I have also tried this variant:
Have you manually created a flow that sends a token and validates the send token?
I'm not sure what your problem is since you did not add any additional information. But what I do know is that by default the password reset functionality won't work unless you set a value in the web.config.
Have you set an UmbracoMembershipProvider in the web.config?
The value
allowManuallyChangingPassword
must be set to true.I am working in version 9. I haven't got a web.config file.
The membership commands differs a lot in the .NET Core version.
Sorry hadn't noticed. In that case: do you have the
AllowPasswordReset
set to true?Thank you for showing me that configuration. It did not help med though. I have found a workaround using the PasswordChanger class. I have to compare the token before changing password
Just stumbled on this now. Looking at your original code, I am wondering if you were using the correct token generator method. In your code you use:
Have you tried:
The password reset token generator is probably what you are after. Additionally, you will need to encode the token so it survives the trip back to your change password page. For some reason, the token does not get generated as encoded. Note that you probably don't have to decode it again on the way back in. Hope that helps...
Cheers,
Jamie
Hi Jamie,
I tried this one. With encoded token : It stated that its invalid.
But otherwise it worked.
So Cheers and thanks :)
Regards.
Glad to hear that worked. If you are using your test scenario above where you are immediately testing the validity of the token without leaving your class, you would not need to encode it, but if you are sending the token out via email and returning it via a URL to a browser, you probably will need to encode it. If that helped you and this worked, can you please mark this one as solved?
Cheers,
Jamie
I tried
GenerateEmailConfirmationTokenAsync()
as well, but then got Invalid Token error later when usingChangePasswordWithResetAsync()
It works as expected when using
GeneratePasswordResetTokenAsync()
though.Later a new password if set from previous generated token.
Not sure if the
GenerateEmailConfirmationTokenAsync()
shouldn't be used for members as I tried a similar approach the user password reset works in backoffice: https://github.com/umbraco/Umbraco-CMS/blob/26d83381f24fa5b11d1564e283660be31e07f82b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs#L572-L580This definitely works for members. Make sure you encode the token in the email outbound. But don’t unencode the token on the way back in. For some reason you don’t need to unencode it.
But email confirmation tokens are for validating/ confirming email addresses, not for resetting passwords. Two different methods for different purposes. For example after a member registers you want to check if there email is legit, you send them an email confirmation token. On the way back in you set email confirmed = true. Then you can test against that and approve their account at that point. Sorry I am on mobile but can post some examples later.
Okay, I was using the
ToUrlBase64()
andFromUrlBase64()
extension methods, so with these it shouldn't be necessary to encode the URL further.The generated token was the same passed into
ChangePasswordWithResetAsync()
but I guess it won't work for this purpose.GeneratePasswordResetTokenAsync()
andChangePasswordWithResetAsync()
seems to do the job.@bjarne When you fetch the member to change the password later using ChangePasswordWithResetAsync, I assume the inviteToken containing the member id at the start (before the | prefix) is used. What prevents someone from changing that id number in the URL and using the link to reset someone elses password?
@Gareth, The token that is generated by
GeneratePasswordResetTokenAsync()
is unique to that user. If a different id or email is used against that token, the change password operations will fail.Cheers,
Jamie
is working on a reply...