overtrue/socialite
Socialite is a lightweight OAuth2 authentication tool for any PHP project, inspired by laravel/socialite. It supports 20+ platforms including GitHub, Google, Facebook, WeChat, Weibo, QQ, Douyin, Alipay, Apple, and Twitter, letting you redirect users and exchange codes for access tokens and profile d...
Installation (assessment current as of 4.15.0):
composer require overtrue/socialite
Ensure PHP ≥ 8.0.2 for the package itself, but note that 4.15.0 now requires guzzlehttp/guzzle: ^8.1 — check composer why-not guzzlehttp/guzzle 8.1 after install, because Guzzle 8 raises the effective PHP floor for the whole dependency graph.
If your app cannot move to Guzzle 8 yet (e.g. Laravel's HTTP client, Flysystem adapters, or SDKs pinned to ^7.0), stay on the 4.14.x line:
composer require overtrue/socialite:^4.14
Basic Configuration:
Define provider configs in an array (e.g., config/social.php):
return [
'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect_uri' => env('GITHUB_REDIRECT_URI'),
],
];
First Use Case: Redirect users to GitHub for OAuth:
use Overtrue\Socialite\SocialiteManager;
$config = require __DIR__.'/config/social.php';
$socialite = new SocialiteManager($config);
$url = $socialite->create('github')->redirect();
return redirect($url);
Callback Handling: Process the OAuth code in a callback route:
$code = request()->query('code');
$user = $socialite->create('github')->userFromCode($code);
// Access user data: $user->getEmail(), $user->getName(), etc.
Where to look first: src/Providers/ for the provider you need, src/Contracts/ for ProviderInterface / UserInterface, then the README's provider table. Start with the GitHub or Google provider — they exercise the full redirect → code → token → user path with the least provider-specific weirdness.
Provider Initialization:
$socialite = new SocialiteManager($config);
$github = $socialite->create('github'); // or custom alias
Redirect Flow:
$authUrl = $github->redirect(); // Returns URL for OAuth redirect
User Data Fetching:
$user = $github->userFromCode($code); // After callback
$user->getId(); // Unique provider ID
$user->getEmail(); // Email (if available)
$user->getAvatar(); // Profile image URL
Token Management:
$token = $github->getAccessToken(); // After userFromCode()
$user = $github->userFromToken($token); // Re-fetch user
Bind the Manager as a Singleton:
Don't new SocialiteManager(...) in every controller — register it once so config and the Guzzle client are shared:
// AppServiceProvider::register()
$this->app->singleton(SocialiteManager::class, function ($app) {
return new SocialiteManager(config('social'));
});
Laravel Integration:
Use overtrue/laravel-socialite for seamless Laravel integration (middleware, service providers, Socialite facade). Verify its own Guzzle constraint before upgrading overtrue/socialite to 4.15.0 — a wrapper still on Guzzle 7 will block the install.
use Overtrue\LaravelSocialite\Facades\Socialite;
$user = Socialite::driver('github')->user();
Custom Scopes:
$url = $github->scopes(['user:email'])->redirect();
State Parameter:
$url = $github->state('custom_state')->redirect();
// Verify in callback: $github->getState() === 'custom_state'
Session Storage: Store tokens/user data in the session for later use:
session(['github_token' => $token]);
Multi-Provider Support:
$providers = ['github', 'google'];
foreach ($providers as $provider) {
$socialite->create($provider)->redirect();
}
Routing: Keep the callback route outside auth middleware and exempt from CSRF (api group or withoutMiddleware(VerifyCsrfToken::class)) — the provider posts/redirects back without your token.
Guzzle 7 → 8 is the headline change:
4.15.0 requires guzzlehttp/guzzle: ^8.1. This is a major-version dependency bump, so the practical breakage is usually Composer-level, not API-level: any package in your lock file requiring guzzlehttp/guzzle: ^7.0 will make the upgrade unresolvable.composer why guzzlehttp/guzzle
composer update overtrue/socialite --with-all-dependencies -W
overtrue/socialite:^4.14 and defer. Nothing in the OAuth flow itself changes.GuzzleHttp\ClientInterface in your own wrapper, custom middlewares on the handler stack, MockHandler in tests) may need adjustment against Guzzle 8's API.HandlerStack / middleware glue is the most likely thing to break silently: assert a mocked OAuth exchange in a test after upgrading.QQ provider return-type fix (PR #306):
QQProvider's inference for user data. If you previously cast or defensively handled null/array-vs-object results from userFromCode() on QQ, re-test — the returned shape is now the annotated one, and stale workarounds may no longer be needed (or may now be type-incompatible).Republish your lock file deliberately: since 4.15.0 lands with a new transitive tree, run the full test suite and a smoke test of one real OAuth round-trip per provider in staging before rolling out.
Redirect URI Mismatch:
redirect_uri in config matches the callback URL registered in the provider's developer console.https://example.com/callback).State Validation:
state parameter in callbacks to prevent CSRF:
if ($github->getState() !== session('oauth_state')) {
throw new \Exception('State mismatch!');
}
Token Expiry:
Overtrue\Socialite\Exceptions\TokenExpiredException by refreshing tokens or re-authenticating.Provider-Specific Quirks:
scope parameter (e.g., all).openid for token-based user fetching:
$user = $douyin->withOpenId($openid)->userFromToken($token);
CORS Issues:
Enable Debug Mode:
$socialite->setDebug(true); // Logs OAuth requests/responses
Inspect Raw Responses:
$response = $github->getAccessTokenResponse($code);
// Dump $response for debugging
Handle Provider Errors: Catch exceptions for specific providers:
try {
$user = $github->userFromCode($code);
} catch (\Overtrue\Socialite\Exceptions\InvalidStateException $e) {
// Handle invalid state
}
Isolate transport bugs after the Guzzle bump: if a call starts throwing GuzzleHttp\Exception\*, reproduce with a bare client against the same URL to separate "provider changed" from "transport changed".
Custom User Model: Map provider data to your user model:
$userData = $github->user()->toArray();
$yourUser = YourUser::updateOrCreate(
['provider_id' => $userData['id']],
[
'name' => $userData['name'],
'email' => $userData['email'] ?? null,
]
);
Extend Providers:
Add support for unsupported providers by implementing ProviderInterface:
class CustomProvider implements \Overtrue\Socialite\Contracts\ProviderInterface {
public function getAuthUrl($state) { /* ... */ }
public function getAccessToken($code) { /* ... */ }
public function getUserByToken($token) { /* ... */ }
}
Register it:
$socialite->extend('custom', function ($config) {
return new CustomProvider($config);
});
Override Default Scopes:
$github->scopes(['user', 'repo']); // Override default scopes
Custom Redirect Logic:
$github->setRedirectUrlGenerator(function ($url) {
return str_replace('https://', 'http://', $url); // Force HTTP
});
redirect or redirect_url for backward compatibility..env or PHP's getenv() for sensitive data (e.g., client_secret).'twitter' => ['provider' => 'twitter', ...]).overtrue/socialite line (^4.15 vs ^4.14) in your composer constraints so the Guzzle 8 requirement is an explicit decision rather than an accident of composer update.How can I help you explore Laravel packages today?