I'm trying to figure out why my users are getting frequent invalid tokens when confirming their email. I can't reproduce the issue.
我想弄明白为什么我的用户在确认他们的电子邮件时经常收到无效的令牌。我无法重现这个问题。
Here's the setup:
这是设置:
userManager.UserTokenProvider = new EmailTokenProvider<User>();
Here's how the token is generated:
下面是如何生成令牌的:
var code = await userManager.GenerateEmailConfirmationTokenAsync(user.Id);
Here's how it's verified:
如何验证:
var result = await userManager.ConfirmEmailAsync(user.Id, code);
I understand that the EmailTokenProvider
uses security stamp for invalidation. My understanding is that this stamp only changes when significant changes to the User entity are made like changing password or username. However I'm getting invalid tokens way more frequently for this to be the only explanation.
我理解EmailTokenProvider使用安全戳进行失效。我的理解是,只有当对用户实体进行重大更改(如更改密码或用户名)时,该戳记才会更改。但是,我越来越频繁地使用无效的令牌,这是唯一的解释。
I'm looking for any pointer that would help me shed some light into why this is occurring.
我正在寻找任何可以帮助我解释为什么会发生这种情况的指针。
Edit:
编辑:
I dug around the source code (documentation is very poor) and as @trailmax pointed out below EmailTokenProvider
is wrong for this use-case. It is based on TotpSecurityStampBasedTokenProvider
which has hard-coded timeout on tokens to 3 minutes!
我在源代码中挖掘(文档非常糟糕),@trailmax指出,在EmailTokenProvider下面,这个用例是错误的。它基于TotpSecurityStampBasedTokenProvider,它对令牌进行了硬编码超时,为3分钟!
1 个解决方案
#1
8
EmailTokenProvider
generates very short-lived token and looks like 6 digits. This token is aimed to be a 2FA and only valid for short period of time (something like 10-15 minutes, don't know the actual value).
EmailTokenProvider生成非常短的令牌,看起来像6位数字。这个标记的目的是成为一个2FA,并且只在短时间内有效(大约10-15分钟,不知道实际值)。
The best you can do is to use Identity-provided DataProtectorTokenProvider
and that's a bit tricky, because it is not simple to rip it out of OWIN's hands.
您所能做的最好的事情就是使用提供的身份数据保护龟提供程序,这有点棘手,因为从OWIN手中将其取出并不容易。
The way I go around it is assign static variable in my Start.Auth.cs
and then reuse it in UserManager:
我绕过它的方法是在我的Start.Auth中分配静态变量。然后在UserManager中重用它:
public class AuthConfig
{
public static IDataProtectionProvider DataProtectionProvider { get; set; }
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
// do other configuration
}
}
And in then re-assign it in constructor of UserManager:
然后在UserManager的构造函数中重新分配它:
var dataProtectorProvider = AuthConfig.DataProtectionProvider;
var dataProtector = dataProtectorProvider.Create("My Asp.Net Identity");
this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, Guid>(dataProtector)
{
TokenLifespan = TimeSpan.FromHours(24),
};
This way you get very long email token that lasts for 24 hours.
通过这种方式,你可以获得长时间的电子邮件标记,持续24小时。
I've done the same mistake as you did, but had to correct pretty soon as users complained.
我已经做了和你一样的错误,但必须尽快纠正用户的抱怨。
#1
8
EmailTokenProvider
generates very short-lived token and looks like 6 digits. This token is aimed to be a 2FA and only valid for short period of time (something like 10-15 minutes, don't know the actual value).
EmailTokenProvider生成非常短的令牌,看起来像6位数字。这个标记的目的是成为一个2FA,并且只在短时间内有效(大约10-15分钟,不知道实际值)。
The best you can do is to use Identity-provided DataProtectorTokenProvider
and that's a bit tricky, because it is not simple to rip it out of OWIN's hands.
您所能做的最好的事情就是使用提供的身份数据保护龟提供程序,这有点棘手,因为从OWIN手中将其取出并不容易。
The way I go around it is assign static variable in my Start.Auth.cs
and then reuse it in UserManager:
我绕过它的方法是在我的Start.Auth中分配静态变量。然后在UserManager中重用它:
public class AuthConfig
{
public static IDataProtectionProvider DataProtectionProvider { get; set; }
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
}
public void ConfigureAuth(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
// do other configuration
}
}
And in then re-assign it in constructor of UserManager:
然后在UserManager的构造函数中重新分配它:
var dataProtectorProvider = AuthConfig.DataProtectionProvider;
var dataProtector = dataProtectorProvider.Create("My Asp.Net Identity");
this.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, Guid>(dataProtector)
{
TokenLifespan = TimeSpan.FromHours(24),
};
This way you get very long email token that lasts for 24 hours.
通过这种方式,你可以获得长时间的电子邮件标记,持续24小时。
I've done the same mistake as you did, but had to correct pretty soon as users complained.
我已经做了和你一样的错误,但必须尽快纠正用户的抱怨。