web-dev-qa-db-ja.com

デフォルトのMVC5アプリのアカウント関連付けステップ中に外部プロバイダーGoogleおよびFacebookからメールを取得する

どうやら、スコープをStartup.Auth.csFacebookAuthenticationOptionsオブジェクトに追加することにより、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);

Googleプロバイダーで同じことをするには? GoogleAuthenticationOptionsクラス/オブジェクトのx.Scopeプロパティはありません!

25
PussInBoots

更新をご覧くださいATこの投稿の最後!

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;

Googleの場合:

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:以前の答えは混乱していたので、デバッグしたばかりの自分のプロジェクトにあるコードでそれを更新しました。

Update 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 });
        }
    }
    
47
PussInBoots

認証されたユーザーからメールアドレスを取得するには、FacebookAuthenticationOptionsを明示的に設定する必要があります。

MVC5プロジェクトで、これらの行をStartup.Auth.csに追加します。

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

pdateサンプルコードを最小限に減らしました。ちなみに、更新されたコードは問題なく動作します。FacebookとGoogleの両方で試してみました。

6
pedrusky

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-the-email-address-from-facebook

4
Zain Rizvi