google/auth
Official Google Auth library for PHP. Implements OAuth 2.0 and Application Default Credentials (ADC) for authenticating to Google APIs and Google Cloud. Install via Composer and use with HTTP clients like Guzzle to authorize API calls.
Installation:
composer require google/auth
Add to composer.json under require:
"google/auth": "^1.9"
First Use Case: Fetch Application Default Credentials (ADC) for a Google API:
use Google\Auth\ApplicationDefaultCredentials;
$scopes = ['https://www.googleapis.com/auth/drive.readonly'];
$middleware = ApplicationDefaultCredentials::getMiddleware($scopes);
Where to Look First:
Google\Auth\ApplicationDefaultCredentials for ADC setup.Google\Auth\CredentialsLoader for custom credential loading.// Laravel Service Provider (e.g., `GoogleAuthServiceProvider`)
public function register()
{
$this->app->singleton('google.auth.middleware', function ($app) {
$scopes = config('google.scopes');
return ApplicationDefaultCredentials::getMiddleware($scopes);
});
}
// HTTP Client (e.g., `app/Http/Clients/GoogleClient`)
public function __construct()
{
$this->client = new Client([
'handler' => HandlerStack::create()->push(
$this->app->make('google.auth.middleware')
),
'base_uri' => 'https://www.googleapis.com',
]);
}
// Load from JSON file or env
$jsonKey = json_decode(file_get_contents(storage_path('app/google-credentials.json')), true);
$creds = new ServiceAccountCredentials(config('google.scopes'), $jsonKey);
// Cache tokens (e.g., using Laravel Cache)
$cache = new FileSystemCacheItemPool(storage_path('app/google-cache'));
$creds = new FetchAuthTokenCache($creds, [], $cache);
// Middleware
$middleware = new AuthTokenMiddleware($creds);
$middleware = ApplicationDefaultCredentials::getIdTokenMiddleware(
config('google.iap.client_id')
);
// Middleware for verifying Google ID tokens (e.g., in `app/Http/Middleware/VerifyGoogleToken`)
public function handle($request, Closure $next)
{
$idToken = $request->bearerToken();
$auth = new AccessToken();
$auth->verify($idToken, [
'certsLocation' => AccessToken::IAP_CERT_URL,
]);
return $next($request);
}
Laravel Configuration:
Add to config/google.php:
return [
'scopes' => [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/calendar',
],
'credentials_path' => storage_path('app/google-credentials.json'),
'cache' => 'file', // 'memory', 'redis', or custom PSR-6 cache
];
Caching Strategies:
Google\Auth\Cache\MemoryCacheItemPool for short-lived tokens (e.g., testing).FileSystemCacheItemPool for persistence across requests.$cache = new RedisCacheItemPool(
Redis::connection('default')->getClient()
);
Quota Project (GCP Billing):
$creds = ApplicationDefaultCredentials::getCredentials($scopes, [
'quotaProjectId' => config('google.quota_project_id'),
]);
Workload Identity Federation: Use ADC with GCP's Workload Identity to avoid hardcoding credentials:
# Set env var in GCP (e.g., Cloud Run)
GOOGLE_APPLICATION_CREDENTIALS=/var/run/secrets/google.iam.gserviceaccount.com
Credential Validation:
$jsonKey = json_decode($rawJson, true);
if (!isset($jsonKey['type'], $jsonKey['project_id'])) {
throw new \InvalidArgumentException('Invalid credential format');
}
Token Expiry:
$creds = new FetchAuthTokenCache($serviceAccountCreds, [], $cache);
Google\Auth\Exception for token errors (e.g., InvalidCredentials).Scopes:
drive.readonly vs. drive).403 Forbidden often stem from insufficient scopes.Environment Variables:
GOOGLE_APPLICATION_CREDENTIALS must point to a valid JSON key file (not a URL).putenv() sparingly; prefer Laravel's .env:
GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json
Guzzle Version:
getMiddleware().getSubscriber() (deprecated in newer versions).Enable Debug Logging:
$creds = ApplicationDefaultCredentials::getCredentials($scopes, [
'debug' => true,
]);
Logs appear in storage/logs/laravel.log.
Token Inspection:
$token = $creds->fetchAuthToken();
// Decode to check claims
$decoded = (array) json_decode(base64_decode(str_replace('_', '/', str_replace('-', '+', explode('.', $token)[1]))));
Common Errors:
InvalidCredentials: Credential file corrupted or permissions issue.
Fix: Regenerate JSON key in GCP Console.TokenExpired: Token cache stale.
Fix: Clear cache or reduce cache_ttl (default: 3600s).ScopeViolation: Missing scope in request.
Fix: Add scope to $scopes array.Laravel Facades: Create a facade for cleaner syntax:
// app/Facades/GoogleAuth.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class GoogleAuth extends Facade {
protected static function getFacadeAccessor() { return 'google.auth'; }
}
Usage:
$middleware = GoogleAuth::middleware(['scope1', 'scope2']);
Retry Logic:
Handle 401 Unauthorized (token expired) with exponential backoff:
try {
$response = $client->get('...');
} catch (Google\Auth\Exception $e) {
if ($e->getCode() === 401) {
$creds->refresh(); // Manually refresh
retry();
}
throw $e;
}
Testing:
Google\Auth\TestOnly\MockCredentials for unit tests:
$mockCreds = new MockCredentials(['access_token' => 'mock_token']);
$middleware = new AuthTokenMiddleware($mockCreds);
GOOGLE_APPLICATION_CREDENTIALS in .env.testing:
GOOGLE_APPLICATION_CREDENTIALS=/dev/null
Performance:
cache_ttl (e.g., 300s for shorter-lived tokens).Google\Auth\CredentialsLoader with a shared cache to avoid race conditions.Extension Points:
Google\Auth\CredentialsInterface for OAuth2 flows.Google\Auth\Cache\CacheItemPoolInterface for custom storage (e.g., DynamoDB).How can I help you explore Laravel packages today?