Why google Oauth verifyIdToken (javascript nodejs version) doesn't use client-secret?

4.1k views Asked by At

I'm testing google singin for a SPA js+nodejs app. I've added this:

<script src="https://apis.google.com/js/platform.js" async defer></script>

and these:

<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
<div class="g-signin2" data-onsuccess="onSignIn"></div>

in html5/js client side. following this guide:

https://developers.google.com/identity/sign-in/web/sign-in

when the users authenticate the library gets the token and pass it to the server as explained here:

https://developers.google.com/identity/sign-in/web/backend-auth

on server side (nodejs) the token is verified using this function:

client.verifyIdToken(
    token,
    CLIENT_ID,
    // Or, if multiple clients access the backend:
    //[CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3],
    function(e, login) {
      var payload = login.getPayload();
      var userid = payload['sub'];
      // If request specified a G Suite domain:
      //var domain = payload['hd'];
    });

MY QUESTION IS: when is the client_secret used? as I've used CLIENT_ID front end to get the auth token from google then I've used CLIENT_ID server side for token verification. I thought that the token could have been verified using client_secret (that is SECRET) known only server side so that no one else getting the token can auth that user. What am I missing?

2

There are 2 answers

1
UchihaItachi On BEST ANSWER

It appears the Client you have created is a Public client , The Client Secret is used in a Private Client .

Edit : I am sorry I used the term private client instead of Confidential client . Basically we have 2 types of clients in Oauth2

  1. Public Clients :- These are clients which don't need a client secret .

  2. Private Clients :- These clients have a Client secret .

I cannot give you a very certain answer as to why you do not get to see your client-secret as I have not worked with these specific libraries before , however it seems to me that may be you had a created a public client instead of a Confidential one .

0
Allen On

I believe I have the answer,

See here: https://firebase.google.com/docs/auth/admin/verify-id-tokens

It explains how to check the signature of the JWT on your own (if you wanted) and this is also what the google-auth-library is doing. Inside the library, search for verifySignedJwtWithCertsAsync() inside of oauth2client.js. Google handles the signing of the JWT using their own private key during the federated sign in process. By the time the JWT is returned to you and sent to the auth library, it's already been signed. This is great because you never have to touch a private key. It's securely stored at Google, you just let Google handle that part. Then, when you send the JWT up to your server, the key id claim in the header lets the auth library know which public key to use to decode it. If the public key fails to decode it, then the authentication has failed.

Finally, ensure that the ID token was signed by the private key corresponding to the token's kid claim. Grab the public key from https://www.googleapis.com/robot/v1/metadata/x509/[email protected] and use a JWT library to verify the signature. Use the value of max-age in the Cache-Control header of the response from that endpoint to know when to refresh the public keys.

If all the above verifications are successful, you can use the subject (sub) of the ID token as the uid of the corresponding user or device.