Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google "One Tap" Verification: Wrong number of segments in token

In the HTML in the site I have got from the docs here

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

      <div
        id="g_id_onload"
        data-client_id={googleClientID}
        data-login_uri='https://mytestdomain.appspot.com/google'
        data-return_uri={uri}
      ></div>

When the site loads it shows me the prompt to continue with my google account, I click continue and it shows me as logged in, the webhook does get called and I can get the g_csrf_token from the cookie, then I try to verify it using the google-auth-library as described here in the docs which is linked from the one-tap docs here

const { OAuth2Client } = require("google-auth-library");
...
app.post("/google", function(req, res) {
  const idToken = req.cookies.g_csrf_token;
  const audience = process.env.GOOGLE_CLIENT_ID
  const client = new OAuth2Client(audience);
  async function verify() {
    const ticket = await client.verifyIdToken({ idToken, audience });
    const payload = ticket.getPayload();
    const userid = payload["sub"];
    console.log('------------------ userid');
    console.log(userid);
  }
  verify().catch(console.error);
  res.status(200).send({ req });
});

Th error I get is

Error: Wrong number of segments in token: 87ba1eb4d6261b6b      at OAuth2Client.verifySignedJwtWithCertsAsync (/app/node_modules/google-auth-library/build/src/auth/oauth2client.js:525:19)      at OAuth2Client.verifyIdTokenAsync (/app/node_modules/google-auth-library/build/src/auth/oauth2client.js:391:34)      at processTicksAndRejections (internal/process/task_queues.js:97:5)      at async verify (/app/server.js:71:20)

The docs do suggest that we should get the token as a POST parameter as well as in the cookie, I have checked req.body.credential, req.query.credential, req.params.credential but there is no token to be found, from the docs here

After an ID token is returned from Google, it's submitted by an HTTP POST method request to your login endpoint with the parameter name credential.

like image 218
Bill Avatar asked Oct 20 '25 15:10

Bill


1 Answers

I figured it out - we were both using the g_csrf_token cookie for the idToken but that's wrong!

You basically need to get the request.body.credential (or req.body.credential in your case) instead, which is a JWT. Then it should work!

like image 56
Bruno Crosier Avatar answered Oct 22 '25 05:10

Bruno Crosier