在默认的MVC5应用程序中,在帐户关联步骤中从外部提供商Google和Facebook获取电子邮件



显然,您可以通过在Startup.Auth.cs:中向FacebookAuthenticationOptions对象添加作用域来使用Facebook提供程序实现这一点

http://blogs.msdn.com/b/webdev/archive/2013/10/16/get-more-information-from-social-providers-used-in-the-vs-2013-project-templates.aspx

List<string> scope = new List<string>() { "email" };
var x = new FacebookAuthenticationOptions();
x.Scope.Add("email");
...
app.UseFacebookAuthentication(x);

如何与谷歌提供商做同样的事情?GoogleAuthenticationOptions类/对象没有x.Scope属性!

请查看此帖子底部的更新

以下适用于Facebook

StartupAuth.cs:

var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
    AppId = "x",
    AppSecret = "y"
};
facebookAuthenticationOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookAuthenticationOptions);

ExternalLoginCallback方法:

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;

对于谷歌

StartupAuth.cs

app.UseGoogleAuthentication();

ExternalLoginCallback方法(与facebook相同):

var externalIdentity = HttpContext.GetOwinContext().Authentication.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
var emailClaim = externalIdentity.Result.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Email);
var email = emailClaim.Value;

如果我在这里设置断点:

var email = emailClaim.Value;

我在调试器中看到了Facebook和Google的电子邮件地址。

更新1:旧的答案让我感到困惑,所以我用我自己项目中的代码更新了它,我刚刚调试了这些代码,我知道这些代码有效。

更新2:有了新的ASP.NET Identity 2.0 RTM版本,您不再需要本文中的任何代码。获取电子邮件的正确方法是简单地执行以下操作:

  1. Startup.Auth.cs

        app.UseFacebookAuthentication(
           appId: "x",
           appSecret: "y");
        app.UseGoogleAuthentication();
    
  2. AccountController.cs

    //
    // GET: /Account/ExternalLoginCallback
    [AllowAnonymous]
    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 });
        }
    }
    

您需要显式配置FacebookAuthenticationOptions以从经过身份验证的用户获取电子邮件地址。

在您的MVC5项目中,在Startup.Auth.cs 中添加这些行

        var options = new FacebookAuthenticationOptions() {
            AppId = "xxxxxxxx",
            AppSecret = "xxxxxxxxx"
        };
        options.Scope.Add("email");
        app.UseFacebookAuthentication(options);

更新将我的示例代码减少到绝对最小值。顺便说一句,你更新的代码运行良好,我也在Facebook和谷歌上尝试过。

在ASP.NET Core Facebook身份验证中,Facebook中间件似乎不再传入电子邮件,即使您将其添加到作用域中也是如此。你可以通过使用Facebook的Graph Api来请求电子邮件来解决这个问题。

您可以使用任何Facebook Graph Api客户端或滚动自己的客户端,并使用它调用Graph Api,如下所示:

app.UseFacebookAuthentication(options =>
{
    options.AppId = Configuration["Authentication:Facebook:AppId"];
    options.AppSecret = Configuration["Authentication:Facebook:AppSecret"];
    options.Scope.Add("public_profile");
    options.Scope.Add("email");
    options.Events = new OAuthEvents
    {
        OnCreatingTicket = context => {
            // Use the Facebook Graph Api to get the user's email address
            // and add it to the email claim
            var client = new FacebookClient(context.AccessToken);
            dynamic info = client.Get("me", new { fields = "name,id,email" });
            context.Identity.AddClaim(new Claim(ClaimTypes.Email, info.email));
            return Task.FromResult(0);
        }
    };
});

你可以在这里找到一个关于如何使用它的更详细的例子:http://zainrizvi.io/2016/03/24/create-site-with-facebook-login-using-asp.net-core/#getting-来自facebook 的电子邮件地址

最新更新