与谷歌和Facebook的AspNet核心外部认证

时间:2016-10-29 09:48:54

标签: asp.net-core asp.net-identity forms-authentication google-signin facebook-authentication

我正在尝试使用Google和Facebook身份验证在ASP.Net Core中实现表单身份验证。我遵循了一些教程,经过一番挣扎,我设法使它兼得。

然而,问题是我不能对同一封电子邮件使用这两种身份验证。

例如,我的电子邮件是' ttcg@gmail.com'。 我使用Facebook身份验证首先登录...注册我的电子邮件,它成功运行并将我的记录放入' dbo.ASPNetUsers'表

然后我退出了,点击Google身份验证即可登录。它已成功验证,但是当我尝试注册时,它一直说我的电子邮件已被删除。

enter image description here

我试图为其他在线网站做同样的事情(例如,Stackoverflow)。我在Google和Facebook上都使用了相同的电子邮件,网站知道,我是同一个人,即使他们来自不同的地方(谷歌和Facebook),我的登录/声明都是链接的。

enter image description here

我想在我的网站上有这个功能,请你告诉我如何实现这一目标。

理论上,它应该在“dbo.AspNetUserLogins'中添加另一行。并应链接相同的UserId与多个登录。

我是否需要实现自己的SignInManager.SignInAsync方法来实现该功能?或者我错过了任何配置?

enter image description here

1 个答案:

答案 0 :(得分:1)

您需要使用UserManager.AddLoginAsync通过电子邮件将Facebook外部登录信息与Google外部登录信息相关联,如果您使用adresse登录,则无法使用相同的地址注册两次。
查看Identity github repo上的Identity示例。

https://github.com/aspnet/Identity/blob/dev/samples/IdentitySample.Mvc/Controllers/ManageController.cs

要将外部登录链接到用户,Manae控制器会公开方法LinkLoginLinkLoginCallback
LinkLogin请求重定向到外部登录提供程序以链接当前用户的登录 LinkLoginCallback处理提供者响应

    //
    // POST: /Manage/LinkLogin
    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult LinkLogin(string provider)
    {
        // Request a redirect to the external login provider to link a login for the current user
        var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
        var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
        return Challenge(properties, provider);
    }

    //
    // GET: /Manage/LinkLoginCallback
    [HttpGet]
    public async Task<ActionResult> LinkLoginCallback()
    {
        var user = await GetCurrentUserAsync();
        if (user == null)
        {
            return View("Error");
        }
        var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
        if (info == null)
        {
            return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
        }
        var result = await _userManager.AddLoginAsync(user, info);
        var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
        return RedirectToAction(nameof(ManageLogins), new { Message = message });
    }