Wrong number of segments in token (OAuth Google Api with php)

I have a php application that use OAuth2 to authenticate users to their account.

until yesterday, everything worked very well.

But today, and without changing my code, when I try to access to my account, and after I authenticates to my google account, I obtain a blank page.

I debug the code and I found that it crashed when the Google_Client try to verifyIdToken and more exactly in the function verifySignedJwtWithCerts because : $segments = explode(".", $jwt); find 4 segments and not 3.

here is my code :

...
$client = new Google_Client();
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($redirectUri);
$client->setScopes("email");

if(!isset($_GET['code']))
    header("Location: ".$client->createAuthUrl());
else
{
    $client->authenticate($_GET['code']);
    $_SESSION["access_token"] = $client->getAccessToken();


    if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
      $client->setAccessToken($_SESSION['access_token']);
    } else {
      $authUrl = $client->createAuthUrl();
    }

    $ticket = $client->verifyIdToken();
    if ($ticket) {
        $admin = $ticket->getAttributes();

    }
    $_SESSION["email"] = $admin["payload"]["email"];

    ...

Can anyone offer an explanation? Thank's in advance

Upvotes: 7

Views: 15000

Answers (2)

ncutixavier
ncutixavier

Reputation: 649

On my side, I've been working on MERN Application and, the issue was on the way I send the tokenId on the backend.

Check if the idToken you are sending to the backend is the same as the one you are getting on googleSuccess.

before.

const onGoogleSuccess = (response) => {
    const tokenId = response.accessToken;//Wrong
    console.log("SUCCESS::", response);

    dispatch(login({ tokenId })).then((res) => {
      console.log("GOOGLE-LOGIN::", res);
    });
  };

After: before.

const onGoogleSuccess = (response) => {
    const tokenId = response.accessToken;
    console.log("SUCCESS::", response);

    dispatch(login({ tokenId })).then((res) => {
      console.log("GOOGLE-LOGIN::", res);
    });
  };

Upvotes: -4

Eddy Goh
Eddy Goh

Reputation: 286

Some how I didn't find any answer in Google. So I going to share what I do to make it work.

The short answer: Because the token you use in verifyIdToken() is invalid.

The long answer as below:

I'm not sure if it is the correct steps:

  1. After Google Login Authentication, we will get the "Authorization Code" from oauthplayground (for testing). Please enter your oauth client_id and oauth client secret in the setting before usage.
  2. I have use the "Authorization Code" to get the other tokens by writing $token = $client->fetchAccessTokenWithAuthCode("THE_AUTHORIZATION_CODE");
  3. Inside $token, I have receive the following: access_token, token_type, expires_in, refresh_token, id_token, created.
  4. Now use the id_token in $payload = $client->verifyIdToken(id_token);
  5. Then you will get the correct information you needed like names, aud, exp, iss etc in $payload.

Note: To avoid your code return the "Wrong number of segments in token" error again, you have to try and catch the verifyIdToken method

try {
     $payload = $client->verifyIdToken(id_token);
}
catch (Exception $e) {
     echo "Invalid id token";
}

Upvotes: 7

Related Questions