如何在IdentityUser中创建备用第二因素?AspNetCore 2.0令牌扩展咨询
嘿,这个问题我之前也碰到过!在ASP.NET Core 2.0的Identity系统里,完全不需要重建整个DbContext就能扩展用户令牌的查询逻辑,给你几个实用的方案:
方案1:给UserManager写扩展方法(最推荐)
Identity的UserManager本身就封装了对用户令牌的底层访问,我们可以通过扩展方法来添加自定义查询,完全不用碰DbContext。
示例代码:
public static class UserManagerExtensions { public static async Task<IdentityUserToken<string>> GetUserTokenByTypeAsync( this UserManager<IdentityUser> userManager, IdentityUser user, string loginProvider, string tokenType) { // 获取底层的令牌存储实现 var tokenStore = userManager.UserTokenStore as IUserTokenStore<IdentityUser>; if (tokenStore == null) { throw new NotSupportedException("当前用户存储不支持令牌操作"); } // 调用存储的原生方法查询令牌 return await tokenStore.FindTokenAsync(user, loginProvider, tokenType, CancellationToken.None); } }
使用的时候直接在代码里调用:
// 假设_userManager是注入的UserManager实例 var backupToken = await _userManager.GetUserTokenByTypeAsync(currentUser, "BackupTwoFactor", "BackupToken");
这个方法的好处是完全遵循Identity的设计模式,不需要改动DbContext,也不会破坏现有逻辑。
方案2:显式暴露UserTokens DbSet
如果你的DbContext继承自IdentityDbContext<IdentityUser>,其实它内部已经包含了UserTokens这个DbSet,只是默认没显式声明。你只需要在自己的DbContext里把它暴露出来就行:
public class ApplicationDbContext : IdentityDbContext<IdentityUser> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } // 显式添加UserTokens DbSet public DbSet<IdentityUserToken<string>> UserTokens { get; set; } }
之后就可以直接注入ApplicationDbContext,写LINQ查询:
var backupToken = await _context.UserTokens .FirstOrDefaultAsync(t => t.UserId == currentUser.Id && t.LoginProvider == "BackupTwoFactor" && t.Name == "BackupToken");
这个方法简单直接,适合需要更复杂查询场景的情况。
方案3:自定义UserTokenStore(灵活度最高)
如果上面两种方法满足不了你的需求,还可以自定义IUserTokenStore实现,替换掉Identity的默认存储,这样就能完全掌控令牌的查询逻辑。
示例实现:
public class CustomUserTokenStore : UserTokenStore<IdentityUser, ApplicationDbContext, string> { public CustomUserTokenStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { } // 添加自定义的查询方法 public async Task<IdentityUserToken<string>> GetBackupTwoFactorTokenAsync(IdentityUser user) { return await Context.UserTokens .FirstOrDefaultAsync(t => t.UserId == user.Id && t.LoginProvider == "BackupTwoFactor" && t.Name == "BackupToken"); } }
然后在Startup的ConfigureServices里替换服务:
services.AddScoped<IUserTokenStore<IdentityUser>, CustomUserTokenStore>();
之后你可以通过UserManager.UserTokenStore转换为自定义类型调用方法,或者直接注入CustomUserTokenStore使用。
内容的提问来源于stack exchange,提问作者Tom Jones
相关产品推荐
相关产品推荐

