How to get google plus profile picture in c# MVC authentication
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
andClientSecret
, 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");