C# ';无效令牌。';通过电子邮件确认ASP.NET MVC时出错
我试图将注册和登录逻辑封装到MVC中的文件中。 一切正常,但我总是收到“无效令牌”。电子邮件确认过程后出错:( 求你了,你能帮我吗?我在搜索解决方案两天后快疯了 我注意到,C# ';无效令牌。';通过电子邮件确认ASP.NET MVC时出错,c#,asp.net,asp.net-mvc,asp.net-mvc-4,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,我试图将注册和登录逻辑封装到MVC中的文件中。 一切正常,但我总是收到“无效令牌”。电子邮件确认过程后出错:( 求你了,你能帮我吗?我在搜索解决方案两天后快疯了 我注意到,GenerateEmailConfirmationToken方法总是生成不同的令牌,如日志文件中所示。可以吗?如果没有存储令牌,它应该总是相同的,对吗 以下是我的存储库构造器以及ASP.NET管理员的准备: UserStore<MyUser> store = null; UserManager<
GenerateEmailConfirmationToken
方法总是生成不同的令牌,如日志文件中所示。可以吗?如果没有存储令牌,它应该总是相同的,对吗
以下是我的存储库构造器以及ASP.NET管理员的准备:
UserStore<MyUser> store = null;
UserManager<MyUser, string> userManager = null;
SignInManager<MyUser, string> signInManager = null;
IAuthenticationManager authenticationManager = null;
AbstractLogger logger = AbstractLogger.GetInstance();
public MyUserRepository(MyDbContext context) : base(context)
{
store = new UserStore<MyUser>(context);
userManager = new UserManager<MyUser>(store);
authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
signInManager = new SignInManager<MyUser, string>(userManager, authenticationManager);
userManager.PasswordValidator = new PasswordValidator()
{
RequireDigit = false,
RequiredLength = 6,
RequireLowercase = false,
RequireNonLetterOrDigit = false,
RequireUppercase = false
};
userManager.UserValidator = new UserValidator<MyUser>(userManager)
{
RequireUniqueEmail = true,
AllowOnlyAlphanumericUserNames = true
};
// Configure user lockout defaults
userManager.UserLockoutEnabledByDefault = true;
userManager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
userManager.MaxFailedAccessAttemptsBeforeLockout = 5;
userManager.EmailService = new EmailService();
var provider = new DpapiDataProtectionProvider("MyApp.org");
userManager.UserTokenProvider = new DataProtectorTokenProvider<MyUser, string>(provider.Create("UserToken")) as IUserTokenProvider<MyUser, string>;
}
以下是日志输出:
USER: 1371ccfd-e8fd-46ed-8bfb-9d51f68aca63
CODE: AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAADOWwoIJFDEqzZ8IvsDocNQAAAAACAAAAAAAQZgAAAAEAACAAAABakUsHl8hIMJX5U5sOc4zEgxUY8ikanoiKoZyIJkttZgAAAAAOgAAAAAIAACAAAADeBcyc9fhA+UR93KdPyWf8zzbJJjAcleIzf4CHCTr3OmAAAABUmOOqZs1FhaSRTcT2gV4V7JRhXNqYuJxJzB0gbo5DDfX1d010qH7YYNe4+iBh6JwdpKXR4tmsPKpojUx3RyPTbKIU8X39CJGqeWAFXAnDZMWKH2ztSn5M5h8V1zrotZRAAAAAVbRUJlIZeKgN/FH5//NQWRBFqKc9GSq0TvMWkYgZeAOyIfTh+JAMoXA4FrYnmJswLZC44zmlZPdisKnsT81ArA==
USER: 1371ccfd-e8fd-46ed-8bfb-9d51f68aca63
CODE: AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAADOWwoIJFDEqzZ8IvsDocNQAAAAACAAAAAAAQZgAAAAEAACAAAABwzJP5VCa/GBicSwTV4Jwu2kt3XvX3xeklIFeJPiYB5QAAAAAOgAAAAAIAACAAAACfIv9bgzQJ9gwyc6Qhn/ml5iQU2qgvO83RiQGbEK/U32AAAACTT2WpFg2BdwLZzWI033SeNK3rUckzxkFkbeFGY7LlkuOhnrjsg/IMyv5YM8sFst8her1bPFi0NDvheSdIWIzWtBQFQZi2VuHRZz3+RiLQllIT/OS/94f1h+yx93QzIGhAAAAAVvPIboy1DrTKpv1easktkMW/olF+MT10MuNlQivcx5wDUSuvzql5GM6GY87Nkm1lFzp9+n0XNWEpbFRqilBuMA==
谢谢。问题确实出在编码上。
代码不应该每次都相同。请使用Url.Action,而不是使用字符串连接创建Url.Url.Action在最新的MVC版本中在幕后进行编码,您可以避免编码和解码操作 下面是您可以使用的代码段
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new
{
userId = user.Id,
code = code,
returnUrl = model.ReturnUrl
}, protocol: Request.Url.Scheme);
如果不想使用
Url.Action
,则可以在生成Url时使用HttpUtility.UrlEncode(code);
对令牌进行编码使用此UserManager.GeneratePasswordResetTokenAsync
方法解决此问题
string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
return RedirectToAction("ResetPassword", "Account", new { userId = user.Id, code = code });
您需要关闭后验证,很抱歉,但我不明白…在第一个链接中,使用了GeneratePasswordResetToken。这不是我的情况。这也不是编码问题,因为每次代码都不同(请参阅日志)。
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account", new
{
userId = user.Id,
code = code,
returnUrl = model.ReturnUrl
}, protocol: Request.Url.Scheme);
string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id);
return RedirectToAction("ResetPassword", "Account", new { userId = user.Id, code = code });