如果使用ASP .Net Identity登录外部登录提供程序,如何保存用户上次登录日期?

Dmy*_*tro 7 c# asp.net asp.net-mvc login asp.net-identity

每次用户登录时,我都会AspNetUser使用LastLoginDate属性扩展类.

public sealed partial class User : IdentityUser<int, UserLogin, UserRole, UserClaim>, IUser<int>, IDatabaseEntity
{
    ...
    public DateTime? LastLoginDate { get; set; }   
}
Run Code Online (Sandbox Code Playgroud)

每次用户使用电子邮件和密码作为登录凭据进行常规登录时,记录工作正常.在AccountController我的登录操作中:

[HttpPost]
public ActionResult Login(LoginModel model)
{
    ...
    var result = SignInManager.PasswordSignIn(model.Email, model.Password, model.RememberMe);

    if (result == SignInStatus.Success)
    {
        var user = UserManager.FindByEmail(email);
        UserManager.RememberLoginDate(user);  
        return Redirect(model.ReturnUrl);
    }

    ...
}
Run Code Online (Sandbox Code Playgroud)

RememberLoginDate只是一种扩展方法,基本上只是将当前时间设置为用户LastLoginDate 属性:

public static IdentityResult RememberLoginDate(this ApplicationUserManager manager, User user)
{
     user.LastLoginDate = DateTime.UtcNow;;
     return manager.Update(user);
}
Run Code Online (Sandbox Code Playgroud)

但是当我像下面那样进行外部登录时:

[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl, string provider)
{
     var loginInfo = AuthenticationManager.GetExternalLoginInfo();
     if (loginInfo == null)
          return RedirectToAction("ExternalLoginFail");

     // Sign in the user with this external login provider if the user already has a login
     var result = SignInManager.ExternalSignIn(loginInfo);
     if (result == SignInStatus.Success)
          return RedirectToLocal(returnUrl);

     if (result == SignInStatus.Failure)
     {
          return View("ExternalLoginConfirmation" ...) 
     }

     ...
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如何记录用户登录日期?我没有关于用户的信息,例如email或在此时Id让他UserManager.我已经尝试过:User.Identity.GetUserId<int>()让用户Id过后SignInManager.ExternalSignIn(loginInfo)但登录后没有更新,它仍然是default(int)- 0.SignInStatus只是enum没有关于已登录用户的其他信息,并且使用ExternalLoginInfo.Email也不是一个选项,因为此电子邮件可能与用户的实际注册电子邮件不同.

小智 4

您应该能够UserManager.FindAsync(loginInfo.Login)通过提供程序和密钥来拉回您的用户 - 这就是 SignInManager 本身的工作原理。