使用Google身份验证进行外部登录

时间:2019-10-04 05:01:51

标签: c# asp.net-core

我正在使用Asp.net核心通过google身份验证登录开发Web应用程序

我成功管理了Google凭据,并在第一时间注册了用户。但是问题甚至在于用户使用Google凭据向应用程序注册,它总是要求为该应用程序一次又一次地注册。

我发现它是由于调用ExternalLoginSignInAsync函数而发生的,并且它总是给出false,我更改了这些参数并尝试了几次  isPersistent:false / true)和bypassTwoFactor:true / false我已经对所有变化进行了测试。但是结果总是错误的。就像我尝试使用正常注册的用户登录名进行Google身份验证一样。

   public async Task<IActionResult> OnGetCallbackAsync(string returnUrl =null,string remoteError = null)
{
            returnUrl = returnUrl ?? Url.Content("~/");
            if (remoteError != null)
            {
                ErrorMessage = $"Error from external provider: 
                {remoteError}";
                return RedirectToPage("./Login", new {ReturnUrl = returnUrl });
            }
            var info = await _signInManager.GetExternalLoginInfoAsync();
            if (info == null)
            {
                ErrorMessage = "Error loading external login information.";
                return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
            }
            var result = await 
               _signInManager.ExternalLoginSignInAsync(info.LoginProvider, 
               info.ProviderKey, isPersistent:false, bypassTwoFactor : true);

            if (result.Succeeded)
            {
                _logger.LogInformation("{Name} logged in with {LoginProvider} 
                provider.", info.Principal.Identity.Name, 
                info.LoginProvider);
                // return LocalRedirect(returnUrl);
                return LocalRedirect("/Customer/ProjectsApiKey/");
            }    

请解决此问题的任何人都能帮到我。我希望对已通过Google身份验证注册或未使用Google身份验证的用户进行检查

2 个答案:

答案 0 :(得分:1)

当GetExternalLoginInfoAsync返回false时,您可以检查用户是否存在,如果该用户存在,则添加登录名。

否则,用户没有帐户,然后要求用户创建一个帐户。

    var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
    if (result.Succeeded)
    {
        return RedirectToAction("Index", "Home");
    }
    if (result.IsLockedOut)
    {
        return RedirectToAction(nameof(Lockout));
    }
    else
    {
        var user = await _userManager.FindByEmailAsync(email);
        if (user != null)
        {
            var resultTemp = await _userManager.AddLoginAsync(user, info);
            if (resultTemp.Succeeded)
            {
                await _signInManager.SignInAsync(user, isPersistent: true);
                return RedirectToAction("Index", "Home");
            }
        }
        // User does not have an account, then ask the user to create an account.
        ViewData["ReturnUrl"] = returnUrl;
        ViewData["LoginProvider"] = info.LoginProvider;
        var email = info.Principal.FindFirstValue(ClaimTypes.Email);
        return View("ExternalLogin", new ExternalLoginViewModel { Email = email });
    }

答案 1 :(得分:1)

我终于找到了故障,这是由于电子邮件确认所致,在我的startup.cs类中,我添加了

 config.SignIn.RequireConfirmedEmail = true;


public void ConfigureServices(IServiceCollection services)
{

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));

    services.AddDefaultIdentity<IdentityUser>(config =>
    {
        config.SignIn.RequireConfirmedEmail = true;
    })
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    // requires
    // using Microsoft.AspNetCore.Identity.UI.Services;
    // using WebPWrecover.Services;
    services.AddTransient<IEmailSender, EmailSender>();
    services.Configure<AuthMessageSenderOptions>(Configuration);

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

由于此,即使我们使用Google身份验证,也始终需要确认用户登录电子邮件。为了解决此问题,当我使用Google身份验证登录创建新用户时,我设置了包括EmailConfirmation = true在内的用户参数用户名和用户电子邮件。然后该错误已修复。之后,当我在下面的函数中调用

var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);

public async Task<IActionResult> OnPostConfirmationAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            // Get the information about the user from the external login provider
            var info = await _signInManager.GetExternalLoginInfoAsync();
            if (info == null)
            {
                ErrorMessage = "Error loading external login information during confirmation.";
                return RedirectToPage("./Login", new { ReturnUrl = returnUrl });
            }

            if (ModelState.IsValid)
            {
                // var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };   comment dulith
                var user = new ApplicationUser { UserName = Input.Email, Email = Input.Email ,EmailConfirmed=true};
                var result = await _userManager.CreateAsync(user);
                await _userManager.AddToRoleAsync(user, SD.User);
                if (result.Succeeded)
                {

                    result = await _userManager.AddLoginAsync(user, info);
                    if (result.Succeeded)
                    {
                        await _signInManager.SignInAsync(user, isPersistent: false);
                        _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
                       // return LocalRedirect(returnUrl);
                        return LocalRedirect("/Customer/ProjectsApiKey/");
                    }
                }

如果用户存在

result.Succeeded is true

也非常感谢您之前的回答。