“Continue with GitHub” looks like one button. Wire it to axios.get and nothing happens; reset a password on every login and someone loses theirs. Here is the whole flow in two routes and a link, with the three traps marked.
TL;DR
- The GitHub button is a plain
<a href>, never an XHR. - Credentials live in
config/services.php, read from.env. - Match users on email with
firstOrNew; set a random password only when creating. - If GitHub returns no email, do not create a user.
Socialite sends the browser to GitHub and back. It is not an XHR. A Vue click handler that axios.gets the redirect URL will not follow GitHub’s login page. The control is a normal link. The session it creates is still Laravel’s session, which is the same cookie story as Sanctum for a Vue SPA when the front end is another origin. On the Inertia starter kit the link can live on the existing login page. The architecture is Inertia, a SPA, or Nuxt.
Install#
composer require laravel/socialiteThe client id and secret come from the environment, through config/services.php. Do not read env() in the controller.
'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect' => env('GITHUB_REDIRECT_URI'),
],GITHUB_REDIRECT_URI is the callback you register at GitHub, such as http://localhost:8000/auth/github/callback. The Inertia app served by Sail is http://localhost instead. Use the host the browser actually returns to.
Two routes and a link#
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Laravel\Socialite\Facades\Socialite;
Route::get('/auth/github/redirect', function () {
return Socialite::driver('github')->redirect();
});
Route::get('/auth/github/callback', function () {
$githubUser = Socialite::driver('github')->user();
$user = User::query()->firstOrNew([
'email' => $githubUser->getEmail(),
]);
$user->name = $githubUser->getName() ?: $githubUser->getNickname();
if (! $user->exists) {
$user->password = Hash::make(str()->random(40));
}
$user->save();
Auth::login($user);
return redirect('/dashboard');
});<a href="/auth/github/redirect">Continue with GitHub</a>Resets the password on every login, then Password only on create:
$user = User::updateOrCreate(
['email' => $githubUser->getEmail()],
['name' => $githubUser->getName(), 'password' => Hash::make(str()->random(40))],
);$user = User::query()->firstOrNew(['email' => $githubUser->getEmail()]);
$user->name = $githubUser->getName() ?: $githubUser->getNickname();
if (! $user->exists) {
$user->password = Hash::make(str()->random(40));
}
$user->save();Match on email. Put the random password on the create path only. updateOrCreate with a new password in the second array resets that password on every GitHub login, including for someone who already had one.
Gotcha: no email from GitHub
GitHub does not always return an email. If getEmail() is null, do not insert a user with an empty email. Ask them to make the email visible on GitHub, or store the GitHub id and collect an email yourself. This callback does not invent a second account-linking flow.
The users table from the starter kit requires password. The random string satisfies that column. The person signs in through GitHub, not by typing it.
Run the round trip
- Create an OAuth app at GitHub with the callback URL from
GITHUB_REDIRECT_URI. - Put the id and secret in
.env, thenphp artisan config:clear. - Click Continue with GitHub, approve, and land on
/dashboardlogged in.
Where this stops#
Socialite does not replace Fortify’s password reset. Email and password stay Fortify. The callback above does not check a permission. A new GitHub user is a normal user until you give them one.
Add scopes only when you need an API GitHub will not return by default. The login above uses the default user. Extra scopes are a decision you can point at the Socialite docs, not a list to paste in before the first redirect works.
Recap#
- Socialite is a full-page redirect; use a link.
- Config in
services.php, secrets in.env. firstOrNewon email; password on create only.- Handle a missing email instead of inserting a blank one.
FAQ#
Why does my Vue button not redirect to GitHub?
You are calling the redirect URL with Axios. OAuth needs a full-page navigation, so use a normal link to /auth/github/redirect.
Why does GitHub login reset users’ passwords?
updateOrCreate with a password in the second array overwrites it on every login. Set the password only when the user does not exist yet.
What if GitHub returns a null email?
Do not create the user. Ask them to make an email visible on GitHub, or store the GitHub id and collect an email yourself.
Next steps#
- Laravel Fortify with Vue: email and password stay here.
- Laravel permissions on a Vue page
- Laravel docs: Socialite



