【问题标题】:UserManager FindAsync method callsUserManager FindAsync 方法调用
【发布时间】:2025-12-12 16:20:05
【问题描述】:

新的 ASP.NET MVC 5 项目模板生成一个准备好的 AccountController,包括 UserManager 的基本实现和底层存储(IUserStoreIRoleStore 等)。

本教程展示了如何实现自定义 UserStore 以将用户数据存储在自定义数据源中:http://www.asp.net/identity/overview/extensibility/implementing-a-custom-mysql-aspnet-identity-storage-provider

但是,我实现了自己的 UserStore 并识别了以下内容:

在登录过程中,会调用AccountController 中的UserManager.FindAsync(UserName, Password) 方法:

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        **var user = await UserManager.FindAsync(model.UserName, model.Password);**
        //other code
    }
    return View(model);
}

FindAsync-方法按以下顺序调用底层UserStore-方法:FindByNameAsync -> GetPasswordHashAsync -> FindByIdAsync

我的问题是:为什么同时调用 FindByNameAsync- 和 FindByIdAsync- 方法?这会导致对数据库进行 2 次查询,从而影响性能。

【问题讨论】:

  • UserManager 中的 FindAsync(string username, string password) 方法没有调用 FindByIdAsync,所以调用的是这一行 var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);在 AccountController 的 SignInAsyn 方法中
  • 我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。

标签: asp.net asp.net-mvc


【解决方案1】:

当您的 UserStore 使用 FindByNameAsync() 获取您的用户时,它只会查找并验证用户的存在感。

当您获取用户信息时,您不会将密码返回给应用程序,因此这就是 GetPasswordHashAsync() 方法再次调用数据库以获取用户密码哈希的原因。

【讨论】: