ASP.Net 核心 3.1 身份 - 生成密码重置令牌问题

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

我正在开发一个网站,用户可以在该网站上单击“忘记密码”按钮来重置密码。

目前,验证电子邮件后,以下代码应生成一个令牌以通过电子邮件发送给用户:

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("/");
        }

所有关于此的在线信息似乎都表明这是做事的方式。我也在 Startup.cs 文件中设置了默认令牌提供程序:

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

然而,当生成令牌时,它会生成一个大令牌,例如:

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

这里的问题显然是正斜杠,它会导致路由问题,因此在此处编码:

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

问题是,即便如此,.Net Core 似乎仍未对其进行编码,并在访问生成的 link 时产生以下错误:

这个错误不一定是问题所在,我明白它的重要性。然而,我似乎无法找到任何解释为什么这个令牌会以这种方式表现。所有在线示例似乎都生成了相当标准的 GUID 样式标记,而不是像这样的东西。

有谁知道为什么会这样?

干杯

令牌在我看来很正常。

我认为您想要使用的 URL 编码方法是 Uri.EscapeDataString. What I've personally done is using a UriBuilder 并转义了查询字符串值(在本例中用于电子邮件确认):

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;

对你来说是:

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

var fullUrl = uriBuilder.Uri.AbsoluteUri;

您可能想尝试 Url.Action() 方法:

示例:

    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

请注意,在上面的示例中,电子邮件必须是 HTML,link 才能正常工作