'https://accounts.test.org/insecure/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', 'clientId' => 'aClientID', ]; /** * @expectedException InvalidArgumentException */ public function testIsNullIfAuthorizationUriIsNull() { $o = new OAuth2([]); $this->assertNull($o->buildFullAuthorizationUri()); } /** * @expectedException InvalidArgumentException */ public function testRequiresTheClientId() { $o = new OAuth2([ 'authorizationUri' => 'https://accounts.test.org/auth/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', ]); $o->buildFullAuthorizationUri(); } /** * @expectedException InvalidArgumentException */ public function testRequiresTheRedirectUri() { $o = new OAuth2([ 'authorizationUri' => 'https://accounts.test.org/auth/url', 'clientId' => 'aClientID', ]); $o->buildFullAuthorizationUri(); } /** * @expectedException InvalidArgumentException */ public function testCannotHavePromptAndApprovalPrompt() { $o = new OAuth2([ 'authorizationUri' => 'https://accounts.test.org/auth/url', 'clientId' => 'aClientID', ]); $o->buildFullAuthorizationUri([ 'approval_prompt' => 'an approval prompt', 'prompt' => 'a prompt', ]); } /** * @expectedException InvalidArgumentException */ public function testCannotHaveInsecureAuthorizationUri() { $o = new OAuth2([ 'authorizationUri' => 'http://accounts.test.org/insecure/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', 'clientId' => 'aClientID', ]); $o->buildFullAuthorizationUri(); } /** * @expectedException InvalidArgumentException */ public function testCannotHaveRelativeRedirectUri() { $o = new OAuth2([ 'authorizationUri' => 'http://accounts.test.org/insecure/url', 'redirectUri' => '/redirect/url', 'clientId' => 'aClientID', ]); $o->buildFullAuthorizationUri(); } public function testHasDefaultXXXTypeParams() { $o = new OAuth2($this->minimal); $q = Psr7\parse_query($o->buildFullAuthorizationUri()->getQuery()); $this->assertEquals('code', $q['response_type']); $this->assertEquals('offline', $q['access_type']); } public function testCanBeUrlObject() { $config = array_merge($this->minimal, [ 'authorizationUri' => Psr7\uri_for('https://another/uri'), ]); $o = new OAuth2($config); $this->assertEquals('/uri', $o->buildFullAuthorizationUri()->getPath()); } public function testCanOverrideParams() { $overrides = [ 'access_type' => 'o_access_type', 'client_id' => 'o_client_id', 'redirect_uri' => 'o_redirect_uri', 'response_type' => 'o_response_type', 'state' => 'o_state', ]; $config = array_merge($this->minimal, ['state' => 'the_state']); $o = new OAuth2($config); $q = Psr7\parse_query($o->buildFullAuthorizationUri($overrides)->getQuery()); $this->assertEquals('o_access_type', $q['access_type']); $this->assertEquals('o_client_id', $q['client_id']); $this->assertEquals('o_redirect_uri', $q['redirect_uri']); $this->assertEquals('o_response_type', $q['response_type']); $this->assertEquals('o_state', $q['state']); } public function testIncludesTheScope() { $with_strings = array_merge($this->minimal, ['scope' => 'scope1 scope2']); $o = new OAuth2($with_strings); $q = Psr7\parse_query($o->buildFullAuthorizationUri()->getQuery()); $this->assertEquals('scope1 scope2', $q['scope']); $with_array = array_merge($this->minimal, [ 'scope' => ['scope1', 'scope2'], ]); $o = new OAuth2($with_array); $q = Psr7\parse_query($o->buildFullAuthorizationUri()->getQuery()); $this->assertEquals('scope1 scope2', $q['scope']); } public function testRedirectUriPostmessageIsAllowed() { $o = new OAuth2([ 'authorizationUri' => 'https://accounts.test.org/insecure/url', 'redirectUri' => 'postmessage', 'clientId' => 'aClientID', ]); $this->assertEquals('postmessage', $o->getRedirectUri()); $url = $o->buildFullAuthorizationUri(); $parts = parse_url((string)$url); parse_str($parts['query'], $query); $this->assertArrayHasKey('redirect_uri', $query); $this->assertEquals('postmessage', $query['redirect_uri']); } } class OAuth2GrantTypeTest extends TestCase { private $minimal = [ 'authorizationUri' => 'https://accounts.test.org/insecure/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', 'clientId' => 'aClientID', ]; public function testReturnsNullIfCannotBeInferred() { $o = new OAuth2($this->minimal); $this->assertNull($o->getGrantType()); } public function testInfersAuthorizationCode() { $o = new OAuth2($this->minimal); $o->setCode('an auth code'); $this->assertEquals('authorization_code', $o->getGrantType()); } public function testInfersRefreshToken() { $o = new OAuth2($this->minimal); $o->setRefreshToken('a refresh token'); $this->assertEquals('refresh_token', $o->getGrantType()); } public function testInfersPassword() { $o = new OAuth2($this->minimal); $o->setPassword('a password'); $o->setUsername('a username'); $this->assertEquals('password', $o->getGrantType()); } public function testInfersJwtBearer() { $o = new OAuth2($this->minimal); $o->setIssuer('an issuer'); $o->setSigningKey('a key'); $this->assertEquals('urn:ietf:params:oauth:grant-type:jwt-bearer', $o->getGrantType()); } public function testSetsKnownTypes() { $o = new OAuth2($this->minimal); foreach (OAuth2::$knownGrantTypes as $t) { $o->setGrantType($t); $this->assertEquals($t, $o->getGrantType()); } } public function testSetsUrlAsGrantType() { $o = new OAuth2($this->minimal); $o->setGrantType('http://a/grant/url'); $this->assertEquals('http://a/grant/url', $o->getGrantType()); } } class OAuth2GetCacheKeyTest extends TestCase { private $minimal = [ 'clientID' => 'aClientID', ]; public function testIsNullWithNoScopes() { $o = new OAuth2($this->minimal); $this->assertNull($o->getCacheKey()); } public function testIsScopeIfSingleScope() { $o = new OAuth2($this->minimal); $o->setScope('test/scope/1'); $this->assertEquals('test/scope/1', $o->getCacheKey()); } public function testIsAllScopesWhenScopeIsArray() { $o = new OAuth2($this->minimal); $o->setScope(['test/scope/1', 'test/scope/2']); $this->assertEquals('test/scope/1:test/scope/2', $o->getCacheKey()); } } class OAuth2TimingTest extends TestCase { private $minimal = [ 'authorizationUri' => 'https://accounts.test.org/insecure/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', 'clientId' => 'aClientID', ]; public function testIssuedAtDefaultsToNull() { $o = new OAuth2($this->minimal); $this->assertNull($o->getIssuedAt()); } public function testExpiresAtDefaultsToNull() { $o = new OAuth2($this->minimal); $this->assertNull($o->getExpiresAt()); } public function testExpiresInDefaultsToNull() { $o = new OAuth2($this->minimal); $this->assertNull($o->getExpiresIn()); } public function testSettingExpiresInSetsIssuedAt() { $o = new OAuth2($this->minimal); $this->assertNull($o->getIssuedAt()); $aShortWhile = 5; $o->setExpiresIn($aShortWhile); $this->assertEquals($aShortWhile, $o->getExpiresIn()); $this->assertNotNull($o->getIssuedAt()); } public function testSettingExpiresInSetsExpireAt() { $o = new OAuth2($this->minimal); $this->assertNull($o->getExpiresAt()); $aShortWhile = 5; $o->setExpiresIn($aShortWhile); $this->assertNotNull($o->getExpiresAt()); $this->assertEquals($aShortWhile, $o->getExpiresAt() - $o->getIssuedAt()); } public function testIsNotExpiredByDefault() { $o = new OAuth2($this->minimal); $this->assertFalse($o->isExpired()); } public function testIsNotExpiredIfExpiresAtIsOld() { $o = new OAuth2($this->minimal); $o->setExpiresAt(time() - 2); $this->assertTrue($o->isExpired()); } } class OAuth2GeneralTest extends TestCase { private $minimal = [ 'authorizationUri' => 'https://accounts.test.org/insecure/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', 'clientId' => 'aClientID', ]; /** * @expectedException InvalidArgumentException */ public function testFailsOnUnknownSigningAlgorithm() { $o = new OAuth2($this->minimal); $o->setSigningAlgorithm('this is definitely not an algorithm name'); } public function testAllowsKnownSigningAlgorithms() { $o = new OAuth2($this->minimal); foreach (OAuth2::$knownSigningAlgorithms as $a) { $o->setSigningAlgorithm($a); $this->assertEquals($a, $o->getSigningAlgorithm()); } } /** * @expectedException InvalidArgumentException */ public function testFailsOnRelativeRedirectUri() { $o = new OAuth2($this->minimal); $o->setRedirectUri('/relative/url'); } public function testAllowsUrnRedirectUri() { $urn = 'urn:ietf:wg:oauth:2.0:oob'; $o = new OAuth2($this->minimal); $o->setRedirectUri($urn); $this->assertEquals($urn, $o->getRedirectUri()); } } class OAuth2JwtTest extends TestCase { private $signingMinimal = [ 'signingKey' => 'example_key', 'signingAlgorithm' => 'HS256', 'scope' => 'https://www.googleapis.com/auth/userinfo.profile', 'issuer' => 'app@example.com', 'audience' => 'accounts.google.com', 'clientId' => 'aClientID', ]; /** * @expectedException DomainException */ public function testFailsWithMissingAudience() { $testConfig = $this->signingMinimal; unset($testConfig['audience']); $o = new OAuth2($testConfig); $o->toJwt(); } /** * @expectedException DomainException */ public function testFailsWithMissingIssuer() { $testConfig = $this->signingMinimal; unset($testConfig['issuer']); $o = new OAuth2($testConfig); $o->toJwt(); } /** */ public function testCanHaveNoScope() { $testConfig = $this->signingMinimal; unset($testConfig['scope']); $o = new OAuth2($testConfig); $o->toJwt(); } /** * @expectedException DomainException */ public function testFailsWithMissingSigningKey() { $testConfig = $this->signingMinimal; unset($testConfig['signingKey']); $o = new OAuth2($testConfig); $o->toJwt(); } /** * @expectedException DomainException */ public function testFailsWithMissingSigningAlgorithm() { $testConfig = $this->signingMinimal; unset($testConfig['signingAlgorithm']); $o = new OAuth2($testConfig); $o->toJwt(); } public function testCanHS256EncodeAValidPayload() { $testConfig = $this->signingMinimal; $o = new OAuth2($testConfig); $payload = $o->toJwt(); $roundTrip = $this->jwtDecode($payload, $testConfig['signingKey'], array('HS256')); $this->assertEquals($roundTrip->iss, $testConfig['issuer']); $this->assertEquals($roundTrip->aud, $testConfig['audience']); $this->assertEquals($roundTrip->scope, $testConfig['scope']); } public function testCanRS256EncodeAValidPayload() { $publicKey = file_get_contents(__DIR__ . '/fixtures' . '/public.pem'); $privateKey = file_get_contents(__DIR__ . '/fixtures' . '/private.pem'); $testConfig = $this->signingMinimal; $o = new OAuth2($testConfig); $o->setSigningAlgorithm('RS256'); $o->setSigningKey($privateKey); $payload = $o->toJwt(); $roundTrip = $this->jwtDecode($payload, $publicKey, array('RS256')); $this->assertEquals($roundTrip->iss, $testConfig['issuer']); $this->assertEquals($roundTrip->aud, $testConfig['audience']); $this->assertEquals($roundTrip->scope, $testConfig['scope']); } public function testCanHaveAdditionalClaims() { $publicKey = file_get_contents(__DIR__ . '/fixtures' . '/public.pem'); $privateKey = file_get_contents(__DIR__ . '/fixtures' . '/private.pem'); $testConfig = $this->signingMinimal; $targetAud = '123@456.com'; $testConfig['additionalClaims'] = ['target_audience' => $targetAud]; $o = new OAuth2($testConfig); $o->setSigningAlgorithm('RS256'); $o->setSigningKey($privateKey); $payload = $o->toJwt(); $roundTrip = $this->jwtDecode($payload, $publicKey, array('RS256')); $this->assertEquals($roundTrip->target_audience, $targetAud); } private function jwtDecode() { $args = func_get_args(); $class = 'JWT'; if (class_exists('Firebase\JWT\JWT')) { $class = 'Firebase\JWT\JWT'; } return call_user_func_array("$class::decode", $args); } } class OAuth2GenerateAccessTokenRequestTest extends TestCase { private $tokenRequestMinimal = [ 'tokenCredentialUri' => 'https://tokens_r_us/test', 'scope' => 'https://www.googleapis.com/auth/userinfo.profile', 'issuer' => 'app@example.com', 'audience' => 'accounts.google.com', 'clientId' => 'aClientID', ]; /** * @expectedException DomainException */ public function testFailsIfNoTokenCredentialUri() { $testConfig = $this->tokenRequestMinimal; unset($testConfig['tokenCredentialUri']); $o = new OAuth2($testConfig); $o->generateCredentialsRequest(); } /** * @expectedException DomainException */ public function testFailsIfAuthorizationCodeIsMissing() { $testConfig = $this->tokenRequestMinimal; $testConfig['redirectUri'] = 'https://has/redirect/uri'; $o = new OAuth2($testConfig); $o->generateCredentialsRequest(); } public function testGeneratesAuthorizationCodeRequests() { $testConfig = $this->tokenRequestMinimal; $testConfig['redirectUri'] = 'https://has/redirect/uri'; $o = new OAuth2($testConfig); $o->setCode('an_auth_code'); // Generate the request and confirm that it's correct. $req = $o->generateCredentialsRequest(); $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req); $this->assertEquals('POST', $req->getMethod()); $fields = Psr7\parse_query((string)$req->getBody()); $this->assertEquals('authorization_code', $fields['grant_type']); $this->assertEquals('an_auth_code', $fields['code']); } public function testGeneratesPasswordRequests() { $testConfig = $this->tokenRequestMinimal; $o = new OAuth2($testConfig); $o->setUsername('a_username'); $o->setPassword('a_password'); // Generate the request and confirm that it's correct. $req = $o->generateCredentialsRequest(); $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req); $this->assertEquals('POST', $req->getMethod()); $fields = Psr7\parse_query((string)$req->getBody()); $this->assertEquals('password', $fields['grant_type']); $this->assertEquals('a_password', $fields['password']); $this->assertEquals('a_username', $fields['username']); } public function testGeneratesRefreshTokenRequests() { $testConfig = $this->tokenRequestMinimal; $o = new OAuth2($testConfig); $o->setRefreshToken('a_refresh_token'); // Generate the request and confirm that it's correct. $req = $o->generateCredentialsRequest(); $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req); $this->assertEquals('POST', $req->getMethod()); $fields = Psr7\parse_query((string)$req->getBody()); $this->assertEquals('refresh_token', $fields['grant_type']); $this->assertEquals('a_refresh_token', $fields['refresh_token']); } public function testClientSecretAddedIfSetForAuthorizationCodeRequests() { $testConfig = $this->tokenRequestMinimal; $testConfig['clientSecret'] = 'a_client_secret'; $testConfig['redirectUri'] = 'https://has/redirect/uri'; $o = new OAuth2($testConfig); $o->setCode('an_auth_code'); $request = $o->generateCredentialsRequest(); $fields = Psr7\parse_query((string)$request->getBody()); $this->assertEquals('a_client_secret', $fields['client_secret']); } public function testClientSecretAddedIfSetForRefreshTokenRequests() { $testConfig = $this->tokenRequestMinimal; $testConfig['clientSecret'] = 'a_client_secret'; $o = new OAuth2($testConfig); $o->setRefreshToken('a_refresh_token'); $request = $o->generateCredentialsRequest(); $fields = Psr7\parse_query((string)$request->getBody()); $this->assertEquals('a_client_secret', $fields['client_secret']); } public function testClientSecretAddedIfSetForPasswordRequests() { $testConfig = $this->tokenRequestMinimal; $testConfig['clientSecret'] = 'a_client_secret'; $o = new OAuth2($testConfig); $o->setUsername('a_username'); $o->setPassword('a_password'); $request = $o->generateCredentialsRequest(); $fields = Psr7\parse_query((string)$request->getBody()); $this->assertEquals('a_client_secret', $fields['client_secret']); } public function testGeneratesAssertionRequests() { $testConfig = $this->tokenRequestMinimal; $o = new OAuth2($testConfig); $o->setSigningKey('a_key'); $o->setSigningAlgorithm('HS256'); // Generate the request and confirm that it's correct. $req = $o->generateCredentialsRequest(); $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req); $this->assertEquals('POST', $req->getMethod()); $fields = Psr7\parse_query((string)$req->getBody()); $this->assertEquals(OAuth2::JWT_URN, $fields['grant_type']); $this->assertArrayHasKey('assertion', $fields); } public function testGeneratesExtendedRequests() { $testConfig = $this->tokenRequestMinimal; $o = new OAuth2($testConfig); $o->setGrantType('urn:my_test_grant_type'); $o->setExtensionParams(['my_param' => 'my_value']); // Generate the request and confirm that it's correct. $req = $o->generateCredentialsRequest(); $this->assertInstanceOf('Psr\Http\Message\RequestInterface', $req); $this->assertEquals('POST', $req->getMethod()); $fields = Psr7\parse_query((string)$req->getBody()); $this->assertEquals('my_value', $fields['my_param']); $this->assertEquals('urn:my_test_grant_type', $fields['grant_type']); } } class OAuth2FetchAuthTokenTest extends TestCase { private $fetchAuthTokenMinimal = [ 'tokenCredentialUri' => 'https://tokens_r_us/test', 'scope' => 'https://www.googleapis.com/auth/userinfo.profile', 'signingKey' => 'example_key', 'signingAlgorithm' => 'HS256', 'issuer' => 'app@example.com', 'audience' => 'accounts.google.com', 'clientId' => 'aClientID', ]; /** * @expectedException GuzzleHttp\Exception\ClientException */ public function testFailsOn400() { $testConfig = $this->fetchAuthTokenMinimal; $httpHandler = getHandler([ buildResponse(400), ]); $o = new OAuth2($testConfig); $o->fetchAuthToken($httpHandler); } /** * @expectedException GuzzleHttp\Exception\ServerException */ public function testFailsOn500() { $testConfig = $this->fetchAuthTokenMinimal; $httpHandler = getHandler([ buildResponse(500), ]); $o = new OAuth2($testConfig); $o->fetchAuthToken($httpHandler); } /** * @expectedException Exception * @expectedExceptionMessage Invalid JSON response */ public function testFailsOnNoContentTypeIfResponseIsNotJSON() { $testConfig = $this->fetchAuthTokenMinimal; $notJson = '{"foo": , this is cannot be passed as json" "bar"}'; $httpHandler = getHandler([ buildResponse(200, [], Psr7\stream_for($notJson)), ]); $o = new OAuth2($testConfig); $o->fetchAuthToken($httpHandler); } public function testFetchesJsonResponseOnNoContentTypeOK() { $testConfig = $this->fetchAuthTokenMinimal; $json = '{"foo": "bar"}'; $httpHandler = getHandler([ buildResponse(200, [], Psr7\stream_for($json)), ]); $o = new OAuth2($testConfig); $tokens = $o->fetchAuthToken($httpHandler); $this->assertEquals($tokens['foo'], 'bar'); } public function testFetchesFromFormEncodedResponseOK() { $testConfig = $this->fetchAuthTokenMinimal; $json = 'foo=bar&spice=nice'; $httpHandler = getHandler([ buildResponse( 200, ['Content-Type' => 'application/x-www-form-urlencoded'], Psr7\stream_for($json) ), ]); $o = new OAuth2($testConfig); $tokens = $o->fetchAuthToken($httpHandler); $this->assertEquals($tokens['foo'], 'bar'); $this->assertEquals($tokens['spice'], 'nice'); } public function testUpdatesTokenFieldsOnFetch() { $testConfig = $this->fetchAuthTokenMinimal; $wanted_updates = [ 'expires_at' => '1', 'expires_in' => '57', 'issued_at' => '2', 'access_token' => 'an_access_token', 'id_token' => 'an_id_token', 'refresh_token' => 'a_refresh_token', ]; $json = json_encode($wanted_updates); $httpHandler = getHandler([ buildResponse(200, [], Psr7\stream_for($json)), ]); $o = new OAuth2($testConfig); $this->assertNull($o->getExpiresAt()); $this->assertNull($o->getExpiresIn()); $this->assertNull($o->getIssuedAt()); $this->assertNull($o->getAccessToken()); $this->assertNull($o->getIdToken()); $this->assertNull($o->getRefreshToken()); $tokens = $o->fetchAuthToken($httpHandler); $this->assertEquals(1, $o->getExpiresAt()); $this->assertEquals(57, $o->getExpiresIn()); $this->assertEquals(2, $o->getIssuedAt()); $this->assertEquals('an_access_token', $o->getAccessToken()); $this->assertEquals('an_id_token', $o->getIdToken()); $this->assertEquals('a_refresh_token', $o->getRefreshToken()); } public function testUpdatesTokenFieldsOnFetchMissingRefreshToken() { $testConfig = $this->fetchAuthTokenMinimal; $testConfig['refresh_token'] = 'a_refresh_token'; $wanted_updates = [ 'expires_at' => '1', 'expires_in' => '57', 'issued_at' => '2', 'access_token' => 'an_access_token', 'id_token' => 'an_id_token', ]; $json = json_encode($wanted_updates); $httpHandler = getHandler([ buildResponse(200, [], Psr7\stream_for($json)), ]); $o = new OAuth2($testConfig); $this->assertNull($o->getExpiresAt()); $this->assertNull($o->getExpiresIn()); $this->assertNull($o->getIssuedAt()); $this->assertNull($o->getAccessToken()); $this->assertNull($o->getIdToken()); $this->assertEquals('a_refresh_token', $o->getRefreshToken()); $tokens = $o->fetchAuthToken($httpHandler); $this->assertEquals(1, $o->getExpiresAt()); $this->assertEquals(57, $o->getExpiresIn()); $this->assertEquals(2, $o->getIssuedAt()); $this->assertEquals('an_access_token', $o->getAccessToken()); $this->assertEquals('an_id_token', $o->getIdToken()); $this->assertEquals('a_refresh_token', $o->getRefreshToken()); } } class OAuth2VerifyIdTokenTest extends TestCase { private $publicKey; private $privateKey; private $verifyIdTokenMinimal = [ 'scope' => 'https://www.googleapis.com/auth/userinfo.profile', 'audience' => 'myaccount.on.host.issuer.com', 'issuer' => 'an.issuer.com', 'clientId' => 'myaccount.on.host.issuer.com', ]; public function setUp() { $this->publicKey = file_get_contents(__DIR__ . '/fixtures' . '/public.pem'); $this->privateKey = file_get_contents(__DIR__ . '/fixtures' . '/private.pem'); } /** * @expectedException UnexpectedValueException */ public function testFailsIfIdTokenIsInvalid() { $testConfig = $this->verifyIdTokenMinimal; $not_a_jwt = 'not a jot'; $o = new OAuth2($testConfig); $o->setIdToken($not_a_jwt); $o->verifyIdToken($this->publicKey); } /** * @expectedException DomainException */ public function testFailsIfAudienceIsMissing() { $testConfig = $this->verifyIdTokenMinimal; $now = time(); $origIdToken = [ 'issuer' => $testConfig['issuer'], 'exp' => $now + 65, // arbitrary 'iat' => $now, ]; $o = new OAuth2($testConfig); $jwtIdToken = $this->jwtEncode($origIdToken, $this->privateKey, 'RS256'); $o->setIdToken($jwtIdToken); $o->verifyIdToken($this->publicKey, ['RS256']); } /** * @expectedException DomainException */ public function testFailsIfAudienceIsWrong() { $now = time(); $testConfig = $this->verifyIdTokenMinimal; $origIdToken = [ 'aud' => 'a different audience', 'iss' => $testConfig['issuer'], 'exp' => $now + 65, // arbitrary 'iat' => $now, ]; $o = new OAuth2($testConfig); $jwtIdToken = $this->jwtEncode($origIdToken, $this->privateKey, 'RS256'); $o->setIdToken($jwtIdToken); $o->verifyIdToken($this->publicKey, ['RS256']); } public function testShouldReturnAValidIdToken() { $testConfig = $this->verifyIdTokenMinimal; $now = time(); $origIdToken = [ 'aud' => $testConfig['audience'], 'iss' => $testConfig['issuer'], 'exp' => $now + 65, // arbitrary 'iat' => $now, ]; $o = new OAuth2($testConfig); $alg = 'RS256'; $jwtIdToken = $this->jwtEncode($origIdToken, $this->privateKey, $alg); $o->setIdToken($jwtIdToken); $roundTrip = $o->verifyIdToken($this->publicKey, array($alg)); $this->assertEquals($origIdToken['aud'], $roundTrip->aud); } private function jwtEncode() { $args = func_get_args(); $class = 'JWT'; if (class_exists('Firebase\JWT\JWT')) { $class = 'Firebase\JWT\JWT'; } return call_user_func_array("$class::encode", $args); } }