首页 文章

asp.net身份2外部登录不保存用户登录,登录提供商后无法找到用户

提问于
浏览
1

我在一个新的mvc项目中使用asp.net identity 2(我把它设置为使用int用户id而不是默认的字符串标识符) . 它可以通过现有帐户成功登录,但如果我使用外部登录而不是使用与现有帐户相同的电子邮件,则使用Google登录,我可以使用Google登录并允许该应用,但是当它重定向时我对ExternalLoginCallback动作,它找不到用户 . GetExternalLoginInfoAsync()用于获取loginInfo,但当我将其传递给ExternalSignIn时,在其中,当它调用var user = await UserManager.FindAsync(loginInfo.Login);时,它找不到用户 . FindAsync返回null . 这可能是新身份框架中的错误吗?具有此电子邮件地址的用户已经存在于数据库中,因此它应该能够找到它(我已经验证了它) .

这是控制器动作(与asp.net身份示例项目中的动作完全相同):

public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
    {
        var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
        if (loginInfo == null)
        {
            return RedirectToAction("Login");
        }

        // Sign in the user with this external login provider if the user already has a login
        var result = await SignInHelper.ExternalSignIn(loginInfo, isPersistent: false);
        switch (result)
        {
            case SignInStatus.Success:
                return RedirectToLocal(returnUrl);
            case SignInStatus.LockedOut:
                return View("Lockout");
            case SignInStatus.RequiresTwoFactorAuthentication:
                return RedirectToAction("SendCode", new { ReturnUrl = returnUrl });
            case SignInStatus.Failure:
            default:
                // If the user does not have an account, then prompt the user to create an account
                ViewBag.ReturnUrl = returnUrl;
                ViewBag.LoginProvider = loginInfo.Login.LoginProvider;
                return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = loginInfo.Email });
        }
    }

以下是上述操作中调用的登录方法(也是身份示例项目中的内容):

public async Task<SignInStatus> ExternalSignIn(ExternalLoginInfo loginInfo, bool isPersistent)
    {
        var user = await UserManager.FindAsync(loginInfo.Login);
        if (user == null)
        {
            return SignInStatus.Failure;
        }
        if (await UserManager.IsLockedOutAsync(user.Id))
        {
            return SignInStatus.LockedOut;
        }
        return await SignInOrTwoFactor(user, isPersistent);
    }

如果我将上述方法中的FindAsync更改为FindByEmailAsync,它会找到该用户 - 为什么不通过电子邮件找到该用户?即var user = await UserManager.FindByEmailAsync(loginInfo.Email);

刚做了一些研究,这似乎只有在你将pk更改为int并且必须创建一个新的自定义用户,角色等类时才会发生 .

1 回答

  • 0

    您正在尝试从新设置的标识对象中获取数据,但上下文尚未更新 .

    有两种方法:

    • 等到上下文更新后,暂时不要访问 User.identity 信息,等待下一个电话 .
    • 尝试获取保存更新的上下文 .
    var store = new UserStore<ApplicationUser>(new MyDbContext());   
    var manager = new UserManager(store);    
    manager.UpdateAsync(user);   
    var ctx = store.context;
    ctx.saveChanges();
    

相关问题