diff --git a/src/Google/AccessToken/Verify.php b/src/Google/AccessToken/Verify.php index 52bae0d95..adb2bec90 100644 --- a/src/Google/AccessToken/Verify.php +++ b/src/Google/AccessToken/Verify.php @@ -48,8 +48,11 @@ class Google_AccessToken_Verify * Instantiates the class, but does not initiate the login flow, leaving it * to the discretion of the caller. */ - public function __construct(ClientInterface $http = null, CacheItemPoolInterface $cache = null) - { + public function __construct( + ClientInterface $http = null, + CacheItemPoolInterface $cache = null, + $jwt = null + ) { if (is_null($http)) { $http = new Client(); } @@ -60,7 +63,7 @@ public function __construct(ClientInterface $http = null, CacheItemPoolInterface $this->http = $http; $this->cache = $cache; - $this->jwt = $this->getJwtService(); + $this->jwt = $jwt ?: $this->getJwtService(); } /** diff --git a/src/Google/Client.php b/src/Google/Client.php index 585a6a47f..a95d9a885 100644 --- a/src/Google/Client.php +++ b/src/Google/Client.php @@ -138,6 +138,10 @@ public function __construct(array $config = array()) // function to be called when an access token is fetched // follows the signature function ($cacheKey, $accessToken) 'token_callback' => null, + + // Service class used in Google_Client::verifyIdToken. + // Explicitly pass this in to avoid setting JWT::$leeway + 'jwt' => null, ], $config ); @@ -686,7 +690,8 @@ public function verifyIdToken($idToken = null) { $tokenVerifier = new Google_AccessToken_Verify( $this->getHttpClient(), - $this->getCache() + $this->getCache(), + $this->jwt ); if (is_null($idToken)) { diff --git a/tests/Google/AccessToken/VerifyTest.php b/tests/Google/AccessToken/VerifyTest.php index a641ce843..351814324 100644 --- a/tests/Google/AccessToken/VerifyTest.php +++ b/tests/Google/AccessToken/VerifyTest.php @@ -87,6 +87,33 @@ public function testValidateIdToken() $this->assertTrue(strlen($payload['sub']) > 0); } + /** + * Most of the logic for ID token validation is in AuthTest - + * this is just a general check to ensure we verify a valid + * id token if one exists. + */ + public function testLeewayIsUnchangedWhenPassingInJwt() + { + $this->checkToken(); + + $jwt = $this->getJwtService(); + // set arbitrary leeway so we can check this later + $jwt::$leeway = $leeway = 1.5; + $client = $this->getClient(); + $token = $client->getAccessToken(); + if ($client->isAccessTokenExpired()) { + $token = $client->fetchAccessTokenWithRefreshToken(); + } + $segments = explode('.', $token['id_token']); + $this->assertEquals(3, count($segments)); + // Extract the client ID in this case as it wont be set on the test client. + $data = json_decode($jwt->urlSafeB64Decode($segments[1])); + $verify = new Google_AccessToken_Verify($client->getHttpClient(), null, $jwt); + $payload = $verify->verifyIdToken($token['id_token'], $data->aud); + // verify the leeway is set as it was + $this->assertEquals($leeway, $jwt::$leeway); + } + public function testRetrieveCertsFromLocation() { $client = $this->getClient();