简体   繁体   中英

MVC External Login - Using Google People API

I have a C# MVC project. I am attempting to aid the user registration process by retrieving user information from Google. I would like to access firstname, lastname, email and mobile number. All are required fields. I believe I need to use the Google People API. The Google+ API has been working fine but doesn't have mobile number. I am unsure on how to obtain this data. Currently in startup.auth I have:

        var googleOptions = new GoogleOAuth2AuthenticationOptions()
        {
            ClientId = ConfigurationManager.AppSettings["GoogleClientId"],
            ClientSecret = ConfigurationManager.AppSettings["GoogleClientSecret"],
            Provider = new GoogleOAuth2AuthenticationProvider
            {
                OnAuthenticated = context =>
                {
                    context.Identity.AddClaim(new Claim("urn:google:accesstoken", context.AccessToken, ClaimValueTypes.String, "Google"));
                    context.Identity.AddClaim(new Claim(ClaimTypes.Email, context.Email));
                    context.Identity.AddClaim(new Claim(ClaimTypes.Uri, context.User["image"]["url"].ToString()));
                    return Task.FromResult(true);
                }
            }
        };
        googleOptions.Scope.Add("https://www.googleapis.com/auth/user.phonenumbers.read");
        googleOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email");
        googleOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.profile");
        app.UseGoogleAuthentication(googleOptions);

And in my Controller I have:

        if (loginInfo.Login.LoginProvider == "Google")
        {
            if (loginInfo.Email == null)
                loginInfo.Email = GetSchemasClaimValue(loginInfo, "emailaddress");
            firstName = GetSchemasClaimValue(loginInfo, "givenname");
            lastName = GetSchemasClaimValue(loginInfo, "surname");
            mobilePhone = loginInfo.ExternalIdentity.Claims.FirstOrDefault(c => c.Type == ClaimTypes.MobilePhone);


            //proPic = GetSchemasClaimValue(loginInfo, "uri");
        }

All the information besides mobile phone is accessible and working as desired. I am just unsure of how to retrieve this data. I was hoping it would appear as a Claim in loginInfo but no claim exists for this case. The user is prompted to give the app permission to access mobile phone so I'm a little confused as to why there is no claim. Does a claim needs to be added in my startup.auth? How would that work? Any help would be appreciated.

I have done a similar feature, ie getting data from Google People API, in my sample Xamarin project with backend hosted on Azure Mobile Apps (aka App Services). I did it as following.

using (HttpClient client = new HttpClient())
{
    client.DefaultRequestHeaders.Authorization =
        AuthenticationHeaderValue.Parse("Bearer " + accessToken);

    using (HttpResponseMessage response = await client.GetAsync("https://www.googleapis.com/plus/v1/people/me"))
    {
        var googlePlusUserInfo = 
            JsonConvert.DeserializeObject<GooglePlusUserInfo>(await response.Content.ReadAsStringAsync());

        googlePlusUserInfo.Email = googlePlusUserInfo.Emails.Count() > 0 ? 

        googlePlusUserInfo.Emails.First().EmailAddress : "";

        googlePlusUserInfo.ProfilePicure.ImageUrl = 
        googlePlusUserInfo.ProfilePicure.ImageUrl.Split(new char[] { '?' })[0];

        return googlePlusUserInfo;
    }
}

Complete code on Github .

If phone number is needed to be retrieved, then we can get it using:

googlePlusUserInfo.PhoneNumbers.CanonicalForm

Of course, the model GooglePlusUserInfo needs to be updated as well in order to match the JSON structure returned first. The JSON of the Google user profile with phone number returned is

{
  "resourceName": "people/...",
  "etag": "...",
  "phoneNumbers": [
    {
      "metadata": {
        "primary": true,
        "source": {
          "type": "CONTACT",
          "id": "1"
        }
      },
      "value": "88880000",
      "canonicalForm": "+65888800000",
      "type": "mobile",
      "formattedType": "Mobile"
    }
  ]
}

Hope this helps and please correct me if I'm wrong.

The https://www.googleapis.com/auth/user.phonenumbers.read scope only works with the Google People API . You can't get that info from login.

You'll need to make a request after login to Google People API to get the desired info. See the example in their documentation: https://developers.google.com/people/v1/read-people

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM