I'm developing a C# ASP.NET MVC 5 application that uses Google sign in as a default provider. The login functionality works ok and I can get the e-mail and name of the user. One thing that I need is to get the profile picture of the user.
How can I achieve that?
So far I using the default MVC auth "UseGoogleAuthentication".
Microsoft.Owin.Security.Google.GoogleAuthenticationOptions a = new Microsoft.Owin.Security.Google.GoogleAuthenticationOptions();
var googleOption = new GoogleAuthenticationOptions()
{
Provider = new GoogleAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
var rawUserObjectFromFacebookAsJson = context.Identity;
context.Identity.AddClaim(new Claim("urn:google:name", context.Identity.FindFirstValue(ClaimTypes.Name)));
context.Identity.AddClaim(new Claim("urn:google:email", context.Identity.FindFirstValue(ClaimTypes.Email)));
return Task.FromResult(0);
}
}
};
app.UseGoogleAuthentication(googleOption);
This is how I can get the email address. But what about the profile picture?
Do I need to use another form of authentication?
Simply using https://plus.google.com/s2/photos/profile/me will be enough. Show activity on this post. You can get the URL for the profile image using the people.
A user's profile photo is stored in their Album Archive, at get.google.com/albumarchive, whether it's added by an admin or the user.
The settings are not ticked by default and so that means that that people cannot change their photo even though they may see their photo changed on their Google profile. Click save and it will update the user and the user can then go back and change their picture on their Google profile page.
I know this is a late answer, but found your question while working on the same problem. Here is my solution.
Instead of using GoogleAuthenticationOptions
I used GoogleOAuth2AuthenticationOptions
which means you'll need to set up a project at https://console.developers.google.com/project first to get a ClientId
and ClientSecret
.
At that link (https://console.developers.google.com/project), create a project and then select it.
Then on the left side menu, click on "APIs & auth".
Under "APIs", ensure you have "Google+ API" set to "On".
Then click on "Credentials" (in the left side menu).
Then click on the button "Create new Client ID". Follow the instructions and you will then be provided with a ClientId
and ClientSecret
, take note of both.
Now you have those, the GoogleOAuth2AuthenticationOptions
code looks like this:
var googleOptions = new GoogleOAuth2AuthenticationOptions()
{
ClientId = [INSERT CLIENT ID HERE],
ClientSecret = [INSERT CLIENT SECRET HERE],
Provider = new GoogleOAuth2AuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim("urn:google:name", context.Identity.FindFirstValue(ClaimTypes.Name)));
context.Identity.AddClaim(new Claim("urn:google:email", context.Identity.FindFirstValue(ClaimTypes.Email)));
//This following line is need to retrieve the profile image
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:google:accesstoken", context.AccessToken, ClaimValueTypes.String, "Google"));
return Task.FromResult(0);
}
}
};
app.UseGoogleAuthentication(googleOptions);
Notice that this also adds the access token as a claim so we can use it to retrieve the profile image. The next bit may vary depending on how you have your project set up, but for me, it was in the AccountController
.
In my ExternalLoginCallback
method I check for which login provider is being used and handle the data for Google login. In this section I retrieve the profile image url and store it in a variable with the following code:
//get access token to use in profile image request
var accessToken = loginInfo.ExternalIdentity.Claims.Where(c => c.Type.Equals("urn:google:accesstoken")).Select(c => c.Value).FirstOrDefault();
Uri apiRequestUri = new Uri("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + accessToken);
//request profile image
using (var webClient = new System.Net.WebClient())
{
var json = webClient.DownloadString(apiRequestUri);
dynamic result = JsonConvert.DeserializeObject(json);
userPicture = result.picture;
}
This uses the access token to request the user info from google. It then retrieves the image url from the json data return. You can then save the url to the database in the most appropriate way for your project.
Hope that helps someone.
This might be done easier. Not sure if it was always like this, but here's my code (ASP.NET 5):
private static Task OnGoogleAuthenticated(GoogleAuthenticatedContext context)
{
var identity = ((ClaimsIdentity)context.Principal.Identity);
var pictureUrl = context.User["image"].Value<string>("url");
// Pass the picture url as a claim to be used later in the application
identity.AddClaim(new Claim("pictureUrl", pictureUrl));
return Task.FromResult(0);
}
In the ExternalLoginCallback, the pictureUrl can then be retrieved directly using:
var info = await signInManager.GetExternalLoginInfoAsync();
...
var picture = info.ExternalPrincipal.FindFirstValue("pictureUrl");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With