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 才能正常工作
我正在开发一个网站,用户可以在该网站上单击“忘记密码”按钮来重置密码。
目前,验证电子邮件后,以下代码应生成一个令牌以通过电子邮件发送给用户:
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 才能正常工作