简体   繁体   中英

.NET Core Identity forgot password broken

I am using the scaffolded Identity with .NET 5. I tried the "Forgot Password" link on the login page. This works in that the email is sent with the link to reset the password.

However, clicking on the link in the email leads to an error relating to the base 64 code being malformed. Malformed input: 321 is an invalid input.

在此处输入图像描述

The base 64 code is there but there's an issue with it. The base 64 code is generated with this:

 var code = await _userManager.GeneratePasswordResetTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ResetPassword",
                pageHandler: null,
                values: new { area = "Identity", code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(
                Input.Email,
                "Reset Password",
                $"Please reset your password by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); 

It breaks on the ResetPassword.cshtml.cs GET.

  if (code == null)
        {
            return BadRequest("A code must be supplied for password reset.");
        }
        else
        {
            Input = new InputModel
            {
                Code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(code))
            };
            return Page();
        }

Can anyone point me in the right direction to fixing this? I am not sure it's relevant but I am using SendGrid's SMTP server.

UPDATE. I spotted that there is a trailing inverted comma at the end of the code. Removing this fixes the issue.

 code = code.Replace("'", "");

Now I just need to find out how it's getting there.

Tried and ruled out the following.

  1. Turned off SendGrid link tracking.
  2. Turned off Outlook safelinks.

The above made no difference.

Then it dawned on me that the email link was not rendering as HTML. ie it was showing the link text and not just the "click here".

Then I read that smtp client is now obsolete and MS recommends using MailKit instead.

So I decided to replace my email sender code with the following using Mailkit and the issue went away.

 public Task SendEmailAsync(string email, string subject, string htmlMessage)
    {
        var message = new MimeMessage();
        message.From.Add(new MailboxAddress("(Admin)", "test@test.com"));
        message.To.Add(new MailboxAddress("Recipient Name", email));
        message.Subject = subject;

        message.Body = new TextPart("html")
        {
            Text = htmlMessage
        };

        string Username = _config["MailSettings:Username"];
        string Password = _config["MailSettings:Password"];
        var port = Convert.ToInt32(_config["MailSettings:Port"]);

        using var client = new SmtpClient();

        client.Connect(_config["MailSettings:Host"], port, false);
        client.Authenticate(Username, Password);

        try
        {
            client.Send(message);
            client.Disconnect(true);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }

        return Task.CompletedTask;

    }

I think this is the part that saved the day:

 message.Body = new TextPart("html")
        {
            Text = htmlMessage
        };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM