Ive been going through some threads in order to reset a Member password. Some of the examples are for another version of Umbraco (im after v 10) or if they seem close to what im after i dont seem to have a method that does the trick. Others suggest i need to change the web.config but i dont have a web.config as its running under Umbraco 10 which is on .Net Core.
Could someone give me an example of how to change a members password please?
you can use the memberManager.ChangePasswordAsync method
something like
var member = _memberManager.GetCurrentMemberAsync().Result;
if (member != null)
{
var changePasswordResult =
await _memberManager.ChangePasswordAsync(member,changePassword.Name.ToString(), changePassword.Password);
}
I tried what you suggested using a controller but it didnt work as it did in previous editions of Umbraco. So i created a DocType MemberReset, with a template. In my project i create a new Controller folder and new controller called MemberResetController.
I inherit it with RenderController (Umbraco 10).
I create the Constructor as required for U 10 i.e. ILogger, ICompositeViewEngine etc etc.
The Index method throws an error about same name.
So i change the Index code to include override which allows me to view the page:
public override IActionResult Index()
{
.....
return View("~Views/MemberReset/Index.cshtml");
}
At this stage i add in MemberManager into the constructor, but i dont see any methods to find the member by email?
Some threads suggest i cant add a parameters to this code as part of the Umbraco 10 so how could i pass in the email address from the template?
You can then set the password using the below code
// Check if the password adheres to the the password policy.
IdentityResult validationResult = await _manager.ValidatePasswordAsync(model.NewPassword);
if (validationResult.Succeeded)
{
// Save the password on the member.
IMember member = _memberService.GetByKey(memberIdent);
member.RawPasswordValue = _hasher.HashPassword(model.NewPassword);
_memberService.Save(member);
}
Great, taking a look but i noticed i dont have access to MemberId and ResetToken. Are these needed or have you extended the existing model (think thats RegisterModel)?
When someone arrives to this page, how do i know what member i am resetting the password for?
They are needed to use ChangePasswordWithResetAsync method, but not necesary if you just use the changePassword.
In my flow when a member wants to change a password they are sent an email with a link that contains the token, clicking on the link then directs them to the change password form and populates the token.
So i can send see the token being passed in if i send a request with ?token=1234 but tried using the GUID for an existing member and that resulted in Object not set to an instance on ChangePasswordWithResetAsync (the Name field is empty, though i noticed you are probably populating this somehow on the cshtml page possibly with a valid token), so how should i be populating this token if its not the Member GUID?
BTW for now i have removed the two fields above for now but i have a feeling once i understand how the token is achieved i may have to re-introduce the token field.
var member = _memberService.GetByEmail(model.EmailAddress);
var memberIdentity = _memberManager.FindByIdAsync(member.Id.ToString()).Result;
// we found a user with that email ....
var token = _memberManager.GeneratePasswordResetTokenAsync(memberIdentity).Result;
Ive created an instance of _hasher as IPasswordHasher.
For the form im still not sure what i may have missed. NewPassword, OldPassword dont exist even though i have @using Umbraco.Cms.Core.Models and for _memberManager, ive introduced
@inject MemberManager _memberManager
@{
}
which seems to have resolved the highlighted error but im not sure at this stage if this is ok or not
Ok can give this a go.... So are you saying i should continue to use UmbRegisterController like before
public class MyClassController : UmbRegisterController
Finally, BeginUmbracoForm(MemberController) (on the form) i would imagine youre not using the BackOffice Controller (same name) so i would change this to BeginUmbracoForm(MyClassController) - i ask as im currently seeing the error The Model item passed into teh ViewDataDictionary is of Umbraco.Cms.Core.Models.ContentModel but rrquires Umbraco.Cms.Core.Models.ChangingPasswordModel
can you show me the full code for your view and I will try to explain what you need to do (my form is in a partial view so does not inherit from an umbraco viewpage.
Is this the whole of your view?
That is just a copy of my snippet, how are you displaying this in a page exactly? say for example your home or another page from your site content.
if the snippet is directly in your page then that is why it is complaining about models probably, save the snippet to a new file as I suggested and include it using the
I noticed the ChangingPasswordModel has an ID property, so does this mean i could use the code you listed above to instantiate the memberService and get the user by email passing in the ID or should i set up the email with the token that is sent and use that to change the password for the member?
you would need to pass the ID with the form, it will be null by default.
TBH the changepassword kind of assumes that the member is already logged in, so the Chnagepassword method uses GetCurrentMemberAsync() to get the member who is changing there password.
It really depends what you are actually attempting to do.
I like the idea you have to generate a token in order to initiate the reset password, so i would like to send the email when a user enters their email address for forgetting their password (I can do this and the token code is above just to give you the entire process).
When they click the link i would like the account to be found (lets say using the snippet above but just the New Password field) and the old password would not be required as theyve forgotten it.
My research leaves me to believe it might be the ID listed against the member in Umbraco but i tried that and it didnt work. If i need to get by email address then i think i have to use memberService but continue to use _memberManager.ChangePassword to change the password? If im on the right track and understood this correctly?
OK, that is generally what I do, TBH the member enters their email addres and submit a form, that then sends them an email with the link and token, when they click on the link they get redirected to another form where they enter the new password, the controller then uses the token to set the new password.
If you can wait until tomorrow I can post the code I use, just signing off for the day I'm afraid :)
Ive got a little further in that i can generate the token and reset the password if i have values hardcoded in my code (to ensure all is working).
Since i am using ChangeModelPassword which has Id, oldPssword and NewPassword, i just need to change the password based on the user.
I use this amended code with hardcoded values (which as i mentioned does work)
var passwordvalid = _memberManager.ValidatePasswordAsync(model.NewPassword).Result;
if (passwordvalid.Succeeded)
{
try
{
string token = "1234";
var member = _memberManager.FindByEmailAsync("[email protected]").Result;
var changePasswordResult =
await _memberManager.ResetPasswordAsync(member, token, model.NewPassword);
So do i need to create a new model or is there a cleaner way to achieve this, assuming if the above is correct once the hardcoded values have been converted?
Resetting Member password
Hi
Ive been going through some threads in order to reset a Member password. Some of the examples are for another version of Umbraco (im after v 10) or if they seem close to what im after i dont seem to have a method that does the trick. Others suggest i need to change the web.config but i dont have a web.config as its running under Umbraco 10 which is on .Net Core.
Could someone give me an example of how to change a members password please?
Many thanks
you can use the
memberManager.ChangePasswordAsync
methodsomething like
Is there anyway i could access
memberManager
through the Razor template or best to have this injected from a Controller level?It would be best to use a controller, but you can inject it into a view
Hi Huw
I tried what you suggested using a controller but it didnt work as it did in previous editions of Umbraco. So i created a DocType MemberReset, with a template. In my project i create a new Controller folder and new controller called MemberResetController.
I inherit it with RenderController (Umbraco 10).
I create the Constructor as required for U 10 i.e. ILogger, ICompositeViewEngine etc etc.
The Index method throws an error about same name.
So i change the Index code to include override which allows me to view the page:
At this stage i add in MemberManager into the constructor, but i dont see any methods to find the member by email?
Some threads suggest i cant add a parameters to this code as part of the Umbraco 10 so how could i pass in the email address from the template?
Many thanks
Hi Linx,
To get a member usinng their email you need to use the IMemberService,, so you should probably do something like below instead
You can then set the password using the below code
Thanks Huw, almost there, how are you passing in the model?
Im using RenderController in my class
and if i have a parameterised method (to pass my model) it tells me no overrideable method found?
I'm using a Form which posts to a SurfaceController
In my Forum package however I use an UmbRegisterController
I have a form in a partialview
Great, taking a look but i noticed i dont have access to MemberId and ResetToken. Are these needed or have you extended the existing model (think thats RegisterModel)?
When someone arrives to this page, how do i know what member i am resetting the password for?
Thanks
They are needed to use ChangePasswordWithResetAsync method, but not necesary if you just use the changePassword.
In my flow when a member wants to change a password they are sent an email with a link that contains the token, clicking on the link then directs them to the change password form and populates the token.
So i can send see the token being passed in if i send a request with ?token=1234 but tried using the GUID for an existing member and that resulted in Object not set to an instance on ChangePasswordWithResetAsync (the Name field is empty, though i noticed you are probably populating this somehow on the cshtml page possibly with a valid token), so how should i be populating this token if its not the Member GUID?
BTW for now i have removed the two fields above for now but i have a feeling once i understand how the token is achieved i may have to re-introduce the token field.
Thanks again for your help (:thumbs-up)
you can generate the token using
You could just use a form like this
and a method like
Ive created an instance of _hasher as
IPasswordHasher
.For the form im still not sure what i may have missed. NewPassword, OldPassword dont exist even though i have
@using Umbraco.Cms.Core.Models
and for_memberManager
, ive introducedwhich seems to have resolved the highlighted error but im not sure at this stage if this is ok or not
They aree part of the ChangingPasswordModel. MemberController is an implementation of UmbRegisterController
Change password form partialview
in the MemberController the ChangePassword method is
Ok can give this a go.... So are you saying i should continue to use
UmbRegisterController
like beforeFinally,
BeginUmbracoForm(MemberController)
(on the form) i would imagine youre not using the BackOffice Controller (same name) so i would change this toBeginUmbracoForm(MyClassController)
- i ask as im currently seeing the error The Model item passed into teh ViewDataDictionary is of Umbraco.Cms.Core.Models.ContentModel but rrquires Umbraco.Cms.Core.Models.ChangingPasswordModelThanks
can you show me the full code for your view and I will try to explain what you need to do (my form is in a partial view so does not inherit from an umbraco viewpage.
Here my current code
Needs some tidying but i can take care of that once i have the minimal functionality working :-)
I also need to see the code for your view where you are using the form that posts to the controller
Is this the whole of your view? That is just a copy of my snippet, how are you displaying this in a page exactly? say for example your home or another page from your site content.
in one of your pages you should load that snippet as a partial view
so save the snippet in the Views\Partials folder as _ChangePassword.cshtml and use the code above to display the form in your page
Currently im displaying a standard page in a single template. In this template i have the snippet to ensure all works before making further changes.
I navigate to localhost://test and the page displays the snippet code.
Let me tweak it and hopefully all should click into place :-)
if the snippet is directly in your page then that is why it is complaining about models probably, save the snippet to a new file as I suggested and include it using the
That should take care of the model issues
Looks much better. Thanks for your help.
I noticed the
ChangingPasswordModel
has anID
property, so does this mean i could use the code you listed above to instantiate the memberService and get the user by email passing in the ID or should i set up the email with the token that is sent and use that to change the password for the member?Thanks
you would need to pass the ID with the form, it will be null by default.
TBH the changepassword kind of assumes that the member is already logged in, so the Chnagepassword method uses GetCurrentMemberAsync() to get the member who is changing there password.
It really depends what you are actually attempting to do.
I like the idea you have to generate a token in order to initiate the reset password, so i would like to send the email when a user enters their email address for forgetting their password (I can do this and the token code is above just to give you the entire process).
When they click the link i would like the account to be found (lets say using the snippet above but just the New Password field) and the old password would not be required as theyve forgotten it.
My research leaves me to believe it might be the ID listed against the member in Umbraco but i tried that and it didnt work. If i need to get by email address then i think i have to use
memberService
but continue to use_memberManager.ChangePassword
to change the password? If im on the right track and understood this correctly?Thx
OK, that is generally what I do, TBH the member enters their email addres and submit a form, that then sends them an email with the link and token, when they click on the link they get redirected to another form where they enter the new password, the controller then uses the token to set the new password.
If you can wait until tomorrow I can post the code I use, just signing off for the day I'm afraid :)
Sure no problem and thanks again for your help
Hi
Ive got a little further in that i can generate the token and reset the password if i have values hardcoded in my code (to ensure all is working).
Since i am using ChangeModelPassword which has Id, oldPssword and NewPassword, i just need to change the password based on the user.
I use this amended code with hardcoded values (which as i mentioned does work)
So do i need to create a new model or is there a cleaner way to achieve this, assuming if the above is correct once the hardcoded values have been converted?
Thanks
Hi Linx,
apologies for the delay, I have been in meetings most of the morning. I put together a quick blog post last night which should help.
https://umbraco.themediawizards.co.uk/the-grimoire/members-forgot-password/
Thanks will check this out and report back. Thank you
is working on a reply...