Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.Net Core 3.1 Identity - Generating Password Reset Token Issue

I am developing a site where the users will be able to click a "Forgot My Password" button to reset their passwords.

Currently, once the email has been validated, the following code should generate a token to be emailed to the user:

if(validUser != null)
        {
            var generationTime = DateTime.Now;
            var pwToken = await _userManager.GeneratePasswordResetTokenAsync(validUser);
            await _userManager.UpdateAsync(validUser);

            var url = $"https://{Request.Host}/verify/{HttpUtility.UrlEncode(pwToken)}";

            //EmailHelper.SendMagicLinkEmail(validUser, url, Request);

            return new RedirectResult("/");
        }

All information online regarding this seems to suggest that this is the way to do things. I have set up the Default token providers in the Startup.csfile too:

identityOptions: o => {
                    o.User.RequireUniqueEmail = true;
                    o.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultProvider;
                    o.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultProvider;
                    
                },

Yet when a token is generated it produces a large token such as this:

CfDJ8CnvAYtZf+1IjXpKUM7+umDYEaImg2SPFglPX3Y8RmYpEfg5zpK8xL54lvlbJUd54CaIzzYlff/GU+xKKS8mmG5UdC1zdk24nOsJNpIlmC3P5V72BchS4P9DGFTR77XiKbMAAYymnMomS2zCdTKh+E4bn9RI6FVinMecG1HR7nSHmOI2McbXHBFTanI/0uwxH5WI/Dj4AFTBP39ni7mfKkeWz2nJ5pTemELJJ6pYP50+

The problem here is obviously the forward slashes, which cause issues with routing so are encoded out here:

var url = $"https://{Request.Host}/verify/{HttpUtility.UrlEncode(pwToken)}";

The problem is that even with that, .Net Core seems to un-encode it and produce the following error when the generated link is accessed: error

This error isn't necessarily the issue, and I do understand it's importance. Yet I can't seem to find any explanation as to why this token is behaving this way. All online examples seem to produce a fairly standard GUID style token, not something such as this.

Does anyone know why this might be happening?

Cheers

like image 693
Quasimodo Avatar asked Nov 21 '25 20:11

Quasimodo


2 Answers

You may want to try the Url.Action() method:

Example:

    var token = userManager.GeneratePasswordResetTokenAsync(user).Result;
    var resetLink = Url.Action("ResetPassword","Account", new { token = token }, protocol: HttpContext.Request.Scheme);
    var message = "<a href=\"" + resetLink + "\">Click here to reset your password</a>";
    //Then send your message to the user

Note in the example above the email must be HTML for the link to work

like image 158
coolhand Avatar answered Nov 24 '25 08:11

coolhand


The token looks fairly normal to me.

I think the URL encoding method you'd want to use is Uri.EscapeDataString. What I've personally done is using a UriBuilder and escaped the query string values (in this case for email confirmation):

var uriBuilder = new UriBuilder
{
    Scheme = "https",
    Host = "my.website.com",
    Path = "/confirmEmail",
    Query = $"email={Uri.EscapeDataString(email)}&token={Uri.EscapeDataString(token)}"
};

var fullUrl = uriBuilder.Uri.AbsoluteUri;

For you that'd be:

var uriBuilder = new UriBuilder
{
    Scheme = "https",
    Host = Request.Host,
    Path = $"/verify/{Uri.EscapeDataString(pwToken)}"
};

var fullUrl = uriBuilder.Uri.AbsoluteUri;
like image 40
Xerillio Avatar answered Nov 24 '25 10:11

Xerillio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!