javascriptasp.net-web-apiaccess-tokengoogle-openidgoogle-identity

How to get the Google user openid with authorization token?


I'm trying to implement a google Oauth2 authentication on a vueJs SPA (front) and a ASP.NET CORE WEB API (back).
But I don't know what to do with the authorization code sent after the user properly signedIn.

What I want to achieve :

I want to implement an Oauth2 process using the GSI library to get the user unique OPENID code.

<script src="https://accounts.google.com/gsi/client" async defer></script>

I want to be able to create a custom google SignIn Button that open an authentication popin when clicked on it.

What did I managed to achieve for now ?

I already setup a google sign in flow using the following functions :

google.accounts.id.initialize({...})
      

Then, I'm force to render a google button using this method :

google.accounts.id.renderButton(buttonWrapper, {
          theme: 'outline',
          size: 'medium',
          type: 'standard',
        });

When the user clicks on the button, it opens a signIn popin.
When he register properly, The callback function gives me a response.credential which is a jwtToken
I send the JWTToken to my ASP NET CORE WEB API and validate it :

[...]
var payload = await GoogleJsonWebSignature.ValidateAsync(token);
[...]

The payload gives me user information like his email, his name and... his openId. Success !

Why am I not satisfied with the previous method?

What's happening when I try the Oauth2 ways ?

First, I'm setting up a client.

this.client = google.accounts.oauth2.initTokenClient({
      client_id: this.clientId,
      scope:
        'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid',
      callback: this.onTokenReceivedCallback,
    });

Then I create a custom button that triggers this method on click

function(){
 this.client.requestAccessToken();
}

If the user click on the button, the sign in popin appears.
If the user signIn, the callback function triggers and I get a response that looks like this.

access_token: "ya29.A0ARrdyM_x7n9uh12345678901234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ12345678901234567890ABCDEFGUMZabqaXVDmmomNrfO_bhLIP-9llQNExSZFNZA2mH5Pzeaq_UiE1mNlfQfhVXQyBv0Hbr1dgYUNnWUtBVEFTQVRBU0ZRRl91NjFWNTNYaVpRa3k0cGRXTWlqZ0pwZGd0Zw0165"
authuser: "1"
expires_in: 3599
prompt: "none"
scope: "email profile https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid"
token_type: "Bearer"

Now, the problems starts because I have absolutely no idea what I should do with that access_token.
This code is not a JwtToken so my previous method does not works.
I guess I should send this accessToken to my ASP .NET CORE WEB API.
The doc mention many apis like google calendar, google drive, email etc etc but I'm not interested in any of that.
What I want is very simple :
I would like to retrieve the user OPENID code.
I will use it to search for an existing user in my database.

Every tutorial I read are not clear (for me) about that and they always consider that I'm using an ASP .NET CORE WEB APP which is REALLY different than an ASP .NET CORE WEB API because the user never directly interact with the last one.

Any help would be appreciated.
Thank you for your time and your help.


Solution

  • I finally managed to find a solution that works for me.
    The Access_Token I received was an Authorization Code I could use to consume google apis.
    The only thing I had to do was to send the AccessToken to my personal ASP.NET CORE WebApi.
    Then I just had to write a simple function that my controller could execute :

     public class GoogleUserInfos
        {
            public string Id { get; set; }
            public string Email { get; set; }
            public string Verified_Email { get; set; }
            public string Name { get; set; }
            public string Given_Name { get; set; }
            public string Family_Name { get; set; }
            public string Picture { get; set; }
            public string Locale { get; set; }
        }
    
    public async Task<GoogleUserInfos?> GetGoogleUserInfos(string authCode)
            {
                try
                {
                    using (var client = new HttpClient())
                    {
                        var uri = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + authCode;
                        using (var response = await client.GetAsync(uri))
                        {
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                string responseString = await response.Content.ReadAsStringAsync();
                                var obj = JsonConvert.DeserializeObject<GoogleUserInfos>(responseString);
                                return obj;
                            }
                        }
                    }
                }
                catch
                {
                    return null;
                }
                return null;
            }
    
    

    The function GetGoogleUserInfos take the Access_Token as parameter (named authCode).
    Then it consume the googleApi oauth2 with the following endpoint https://www.googleapis.com/oauth2/v1/userinfo.
    It also send the accessToken as argument in the getRequest.
    Once it get the response, the function deserialize the object in a custom object GoogleUserInfos.
    The Id field of the response is the google user unique OPEN ID which will allow me to link the user with the users I store in my database.