Cos’è Laravel Socialite
Laravel Socialite è il pacchetto ufficiale che semplifica il login social con OAuth 2.0. Supporta i principali provider (GitHub, Google, Facebook, X, LinkedIn) e ti permette di implementare OAuth in poche righe.
Provider inclusi:
Provider Chiave Bitbucket bitbucketFacebook facebookGitHub githubGitLab gitlabGoogle googleLinkedIn (OpenID) linkedin-openidSlack slack / slack-openidSpotify spotifyTwitch twitchX (Twitter) x
Flusso di login social
Installazione
composer require laravel/socialite
Configurazione
config/services.php
'github' => [
'client_id' => env ( 'GITHUB_CLIENT_ID' ),
'client_secret' => env ( 'GITHUB_CLIENT_SECRET' ),
'redirect' => env ( 'GITHUB_REDIRECT_URI' ),
],
'google' => [
'client_id' => env ( 'GOOGLE_CLIENT_ID' ),
'client_secret' => env ( 'GOOGLE_CLIENT_SECRET' ),
'redirect' => env ( 'GOOGLE_REDIRECT_URI' ),
],
'facebook' => [
'client_id' => env ( 'FACEBOOK_CLIENT_ID' ),
'client_secret' => env ( 'FACEBOOK_CLIENT_SECRET' ),
'redirect' => env ( 'FACEBOOK_REDIRECT_URI' ),
],
Path relativi in redirect sono automaticamente risolti in URL completi.
.env
GITHUB_CLIENT_ID =your-client-id
GITHUB_CLIENT_SECRET =your-client-secret
GITHUB_REDIRECT_URI =https://example.com/auth/github/callback
Per GitHub, crea una OAuth App in Developer Settings .
Flusso di autenticazione
Routing
Servono due route (redirect e callback).
use Laravel\Socialite\Facades\ Socialite ;
Route :: get ( '/auth/github' , function () {
return Socialite :: driver ( 'github' ) -> redirect ();
});
Route :: get ( '/auth/github/callback' , function () {
$user = Socialite :: driver ( 'github' ) -> user ();
// $user->token per l'access token
});
Salvataggio utente e login
use App\Models\ User ;
use Illuminate\Support\Facades\ Auth ;
use Laravel\Socialite\Facades\ Socialite ;
Route :: get ( '/auth/github/callback' , function () {
$githubUser = Socialite :: driver ( 'github' ) -> user ();
$user = User :: updateOrCreate (
[ 'github_id' => $githubUser -> id ],
[
'name' => $githubUser -> name ,
'email' => $githubUser -> email ,
'github_token' => $githubUser -> token ,
'github_refresh_token' => $githubUser -> refreshToken ,
]
);
Auth :: login ( $user );
return redirect ( '/dashboard' );
});
Con updateOrCreate la colonna github_id deve esistere in users.
Ottenere info utente
Route :: get ( '/auth/github/callback' , function () {
$user = Socialite :: driver ( 'github' ) -> user ();
// OAuth 2.0
$token = $user -> token ;
$refreshToken = $user -> refreshToken ;
$expiresIn = $user -> expiresIn ;
// OAuth 1.0 (X)
$token = $user -> token ;
$tokenSecret = $user -> tokenSecret ;
// Comuni
$user -> getId ();
$user -> getNickname ();
$user -> getName ();
$user -> getEmail ();
$user -> getAvatar ();
});
Da un token esistente
$user = Socialite :: driver ( 'github' ) -> userFromToken ( $token );
Modalità stateless
return Socialite :: driver ( 'google' ) -> stateless () -> user ();
Integrazione DB
Migration
return new class extends Migration
{
public function up () : void
{
Schema :: table ( 'users' , function ( Blueprint $table ) {
$table -> string ( 'github_id' ) -> nullable () -> unique () -> after ( 'id' );
$table -> string ( 'github_token' ) -> nullable () -> after ( 'github_id' );
$table -> string ( 'github_refresh_token' ) -> nullable () -> after ( 'github_token' );
});
}
public function down () : void
{
Schema :: table ( 'users' , function ( Blueprint $table ) {
$table -> dropColumn ([ 'github_id' , 'github_token' , 'github_refresh_token' ]);
});
}
};
Più provider con colonna provider
Schema :: table ( 'users' , function ( Blueprint $table ) {
$table -> string ( 'provider' ) -> nullable () -> after ( 'id' );
$table -> string ( 'provider_id' ) -> nullable () -> after ( 'provider' );
$table -> string ( 'provider_token' ) -> nullable () -> after ( 'provider_id' );
$table -> unique ([ 'provider' , 'provider_id' ]);
});
Route :: get ( '/auth/{provider}/callback' , function ( string $provider ) {
$socialUser = Socialite :: driver ( $provider ) -> user ();
$user = User :: updateOrCreate (
[
'provider' => $provider ,
'provider_id' => $socialUser -> getId (),
],
[
'name' => $socialUser -> getName (),
'email' => $socialUser -> getEmail (),
'provider_token' => $socialUser -> token ,
]
);
Auth :: login ( $user );
return redirect ( '/dashboard' );
});
Collegamento a utente esistente
$socialUser = Socialite :: driver ( 'github' ) -> user ();
$user = User :: where ( 'email' , $socialUser -> getEmail ()) -> first ();
if ( $user ) {
$user -> update ([
'github_id' => $socialUser -> getId (),
'github_token' => $socialUser -> token ,
]);
} else {
$user = User :: create ([
'name' => $socialUser -> getName (),
'email' => $socialUser -> getEmail (),
'github_id' => $socialUser -> getId (),
'github_token' => $socialUser -> token ,
]);
}
Auth :: login ( $user );
Scope e opzioni
Scope
return Socialite :: driver ( 'github' )
-> scopes ([ 'read:user' , 'public_repo' ])
-> redirect ();
setScopes() sovrascrive quelli esistenti.
return Socialite :: driver ( 'github' )
-> setScopes ([ 'read:user' , 'public_repo' ])
-> redirect ();
Parametri aggiuntivi
return Socialite :: driver ( 'google' )
-> with ([ 'hd' => 'example.com' ])
-> redirect ();
return Socialite :: driver ( 'google' )
-> with ([ 'prompt' => 'consent' ])
-> redirect ();
Non passare a with() chiavi riservate come state o response_type.
Bot token Slack
return Socialite :: driver ( 'slack' )
-> asBotUser ()
-> setScopes ([ 'chat:write' , 'chat:write.public' , 'chat:write.customize' ])
-> redirect ();
$user = Socialite :: driver ( 'slack' ) -> asBotUser () -> user ();
Test
Redirect
use Laravel\Socialite\Facades\ Socialite ;
test ( 'l \' utente viene reindirizzato a GitHub' , function () {
Socialite :: fake ( 'github' );
$response = $this -> get ( '/auth/github' );
$response -> assertRedirect ();
});
Callback
use Laravel\Socialite\Facades\ Socialite ;
use Laravel\Socialite\Two\ User ;
test ( 'login con GitHub' , function () {
Socialite :: fake ( 'github' , User :: fake ([
'id' => 'github-123' ,
'name' => 'Jane Doe' ,
'email' => '[email protected] ' ,
]));
$response = $this -> get ( '/auth/github/callback' );
$response -> assertRedirect ( '/dashboard' );
$this -> assertDatabaseHas ( 'users' , [
'name' => 'Jane Doe' ,
'email' => '[email protected] ' ,
'github_id' => 'github-123' ,
]);
});
Attributi aggiuntivi:
$fakeUser = User :: fake ([
'id' => 'github-123' ,
'name' => 'Jane Doe' ,
'email' => '[email protected] ' ,
'token' => 'fake-token' ,
'refreshToken' => 'fake-refresh-token' ,
'expiresIn' => 3600 ,
'approvedScopes' => [ 'read:user' , 'public_repo' ],
]);
Per OAuth 1 usa Laravel\Socialite\One\User.
Provider personalizzati
Usa Socialite::extend(). SocialiteManager estende Illuminate\Support\Manager.
1. Crea la classe provider
namespace App\Socialite ;
use Laravel\Socialite\Two\ AbstractProvider ;
use Laravel\Socialite\Two\ User ;
class ExampleProvider extends AbstractProvider
{
public function getAuthUrl ( $state ) : string
{
return $this -> buildAuthUrlFromBase ( 'https://example.com/oauth/authorize' , $state );
}
protected function getTokenUrl () : string
{
return 'https://example.com/oauth/token' ;
}
protected function getUserByToken ( $token ) : array
{
$response = $this -> getHttpClient () -> get ( 'https://example.com/api/user' , [
'headers' => [ 'Authorization' => 'Bearer ' . $token ],
]);
return json_decode ( $response -> getBody (), true );
}
protected function mapUserToObject ( array $user ) : User
{
return ( new User ) -> setRaw ( $user ) -> map ([
'id' => $user [ 'id' ],
'nickname' => $user [ 'login' ] ?? null ,
'name' => $user [ 'name' ],
'email' => $user [ 'email' ],
'avatar' => $user [ 'avatar_url' ] ?? null ,
]);
}
}
Metodo Ruolo getAuthUrl($state)URL di autorizzazione OAuth getTokenUrl()Endpoint di scambio code → token getUserByToken($token)Recupera l’utente dall’API con il token mapUserToObject(array $user)Converte in User di Socialite
2. Registralo nel service provider
use App\Socialite\ ExampleProvider ;
use Laravel\Socialite\Facades\ Socialite ;
public function boot () : void
{
Socialite :: extend ( 'example' , function ( $app ) {
$config = $app [ 'config' ][ 'services.example' ];
return Socialite :: buildProvider ( ExampleProvider :: class , $config );
});
}
3. Configura
'example' => [
'client_id' => env ( 'EXAMPLE_CLIENT_ID' ),
'client_secret' => env ( 'EXAMPLE_CLIENT_SECRET' ),
'redirect' => env ( 'EXAMPLE_REDIRECT_URI' ),
],
4. Usalo come i provider integrati
Route :: get ( '/auth/example' , function () {
return Socialite :: driver ( 'example' ) -> redirect ();
});
Route :: get ( '/auth/example/callback' , function () {
$user = Socialite :: driver ( 'example' ) -> user ();
});
Puoi anche usare pacchetti di terze parti che estendono Socialite tramite extend().
Pacchetti correlati
LINE LINE SDK for Laravel. Oltre al login OAuth via Socialite, integra anche Messaging API.
Bluesky Integrazione AT Protocol (Bluesky). Login OAuth e invio post.
Discord Login OAuth2 Discord.
Threads Integrazione Meta Threads.
Mastodon Login OAuth a un’istanza Mastodon.
WordPress Login OAuth WordPress.com o self-hosted.