diff --git a/src/AuthHandler/Guzzle6AuthHandler.php b/src/AuthHandler/Guzzle6AuthHandler.php index 7e8a815c2..0c4d12852 100644 --- a/src/AuthHandler/Guzzle6AuthHandler.php +++ b/src/AuthHandler/Guzzle6AuthHandler.php @@ -74,10 +74,18 @@ public function attachToken(ClientInterface $http, array $token, array $scopes) return $token['access_token']; }; + // Derive a cache prefix from the token, to ensure setting a new token + // results in a cache-miss. + // Note: Supplying a custom "prefix" will bust this behavior. + $cacheConfig = $this->cacheConfig; + if (!isset($cacheConfig['prefix']) && isset($token['access_token'])) { + $cacheConfig['prefix'] = substr(sha1($token['access_token']), -10); + } + $middleware = new ScopedAccessTokenMiddleware( $tokenFunc, $scopes, - $this->cacheConfig, + $cacheConfig, $this->cache ); diff --git a/tests/Google/AuthHandler/AuthHandlerTest.php b/tests/Google/AuthHandler/AuthHandlerTest.php new file mode 100644 index 000000000..0bc34aa82 --- /dev/null +++ b/tests/Google/AuthHandler/AuthHandlerTest.php @@ -0,0 +1,82 @@ +attachToken( + $client, + ['access_token' => '1234'], + $scopes + ); + + // Call our middleware and verify the token is set + $scopedMiddleware = $this->getGoogleAuthMiddleware($http1); + $request = $scopedMiddleware(new Request('GET', '/'), ['auth' => 'scoped']); + $this->assertEquals(['Bearer 1234'], $request->getHeader('Authorization')); + + // Attach a new token to the HTTP client + $http2 = $authHandler->attachToken( + $client, + ['access_token' => '5678'], + $scopes + ); + + // Call our middleware and verify the NEW token is set + $scopedMiddleware = $this->getGoogleAuthMiddleware($http2); + $request = $scopedMiddleware(new Request('GET', '/'), ['auth' => 'scoped']); + $this->assertEquals(['Bearer 5678'], $request->getHeader('Authorization')); + } + + private function getGoogleAuthMiddleware(Client $http) + { + // All sorts of horrible reflection to get at our middleware + $handler = $http->getConfig()['handler']; + $reflectionMethod = new \ReflectionMethod($handler, 'findByName'); + $reflectionMethod->setAccessible(true); + $authMiddlewareIdx = $reflectionMethod->invoke($handler, 'google_auth'); + + $reflectionProperty = new \ReflectionProperty($handler, 'stack'); + $reflectionProperty->setAccessible(true); + $stack = $reflectionProperty->getValue($handler); + + $callable = $stack[$authMiddlewareIdx][0]; + return $callable(function ($request) { + return $request; + }); + } +}