Hello,
I've put this same post in stackoverflow, but I think we will be better here, due is likely a bug.
I have the next code, got directly from google reference (https://developers.google.com/identity/sign-in/web/backend-auth)
public function verifyFromAndroid($idToken=null) {
if(empty($idToken)) {
$idToken = self::SAMPLE_ID_TOKEN;
}
$client = new Google_Client(['client_id' => self::CLIENT_ID]);
$payload = $client->verifyIdToken($idToken);
if ($payload) {
print_r($payload);
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
var_dump($payload);
$this->lastError = "Invalid ID token";
return false;
}
}
But this method always returns false, even using a valid id token that is created and working using the oauthplayground online tool. https://developers.google.com/oauthplayground/
The next code works fine, using directly the GoogleAccessToken_Verify class.
try {
$verify = new Google_AccessToken_Verify();
$result = $verify->verifyIdToken($this->idToken);
if($result) {
print_r($result);
$friendlyData = $this->translateData($result, true);
if(!$friendlyData) {
return false;
}
return $friendlyData;
}
else {
$this->lastError = "Invalid token verification, no error code";
return false;
}
}
catch(UnexpectedValueException $ex) {
$this->lastError = "UnVaEx (Code {$ex->getCode()}): {$ex->getMessage()}";
return false;
}
Can someone tell me why the official Google code doesn't work and yes my own code using the official Google-api-php-client sdk?
I have same issue, i follow google reference but server side verification fail every time.
HTML + Javascript
<script src="https://apis.google.com/js/platform.js" async defer></script>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
// ok here, everything is displayed
var id_token = googleUser.getAuthResponse().id_token;
var xhr = new XMLHttpRequest();
xhr.open('POST', "{{URL("sessions/sso/google");}}");
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
console.log('Signed in as: ' + xhr.responseText);
};
xhr.send('idtoken=' + id_token);
}
</script>
<meta name="google-signin-client_id" content="{{CLIENT_ID}}.apps.googleusercontent.com">
<div class="g-signin2" data-scope="profile email" data-width="298" data-onsuccess="onSignIn"></div>
PHP
$id_token = input::post('idtoken');
$client = new Google_Client(['client_id' => self::client_id]);
$payload = $client->verifyIdToken($id_token);
var_dump($payload);//bool(false)
@mvcmaker if you drop the client id argument from the Google_Client-constructor, does it work then? I had this same problem but the reason was I was using wrong client id..
@ernofi does your verifyToken call work without client_id?
@MarsVard yes it does.
@ernofi @mvcmaker it's working for us without setting a client_id in php, can somebody clarify why the docs are stating otherwise?
We are using a different client_id for android and another one for iOS because we generated a different id for each platform.
And on the web-server we don't set any id while calling verifyToken... this works, while it shouldn't in our opinion.... any ideas?
Edit
Ok, we figured it out.
So if your server gets a token from android, it should use the android client_id, if it gets a token from iOS it should use the iOS client_id to verify the token.
that's it.
note: on iOS you should use an iOS auth client, while on android you should use a web auth client, the android auth client keeps throwing and "Api exception 10"
@MarsVard If you take a look here:
https://github.com/google/google-api-php-client/blob/d669e0f3b92da94d5b4ed960d462dd3b0de920ea/src/Google/AccessToken/Verify.php#L106-L110
It isn't sending the client_id anywhere. It is just comparing it to "aud" property of idToken. So you can do like:
$idToken = 'EAA....etc...';
$iosToken = '[email protected]';
$androidToken = '[email protected]';
$client = new \Google_Client();
$data = $client->verifyIdToken($idToken);
return $data && in_array($data['aud'], [ $iosToken, $androidToken ]);
@ernofi I know, but using the android client_id in android keeps throwing an "ApiException: 10", I'm 100% sure my key sha1 and package name are correct on the developer console
Any idea how to solve this problem?
I have exactly same situation. Except the verification work on local machine and fail on production server.
Local machine running MacOS with LibreSSL 2.2.7
Production server running Ubuntu 16.04 with OpenSSL OpenSSL 1.1.0h 27 Mar 2018
At this moment, this method work for me on both local and production:
$verify = new Google_AccessToken_Verify();
return $verify->verifyIdToken($token);
@oxycoder You might be better served by opening a new issue and explaining you problem in greater detail. Include a code snippet of broken code and what you expect its behavior should be. It also helps to know what API you are trying to access.
This thread seems resolved. If anyone is still having problems let's address them in a new issue.
Most helpful comment
@MarsVard If you take a look here:
https://github.com/google/google-api-php-client/blob/d669e0f3b92da94d5b4ed960d462dd3b0de920ea/src/Google/AccessToken/Verify.php#L106-L110
It isn't sending the client_id anywhere. It is just comparing it to "aud" property of idToken. So you can do like: