php artisan make:migration add_social_fields_to_users_table
Schema::table('users', function (Blueprint $table) {
$table->string('provider_name')->nullable()->after('id');
$table->string('provider_id')->nullable()->after('provider_name');
$table->string('password')->nullable()->change();
$table->string('avatar')->nullable();
});
app/Models/User.php
protected $hidden = [
'provider_name', 'provider_id', 'password', 'remember_token',
];
composer require laravel/socialite
config/auth.php
// ...
'socialite' => [
'drivers' => [
'google',
],
],
// ...
config/services.php
// ...
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT'),
],
// ...
.env
// ...
GOOGLE_CLIENT_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_REDIRECT="${APP_URL}/google/callback"
app/Http/Controllers/SocialLoginController.php
use App\Models\User;
use Exception;
use Illuminate\Http\RedirectResponse;
use Laravel\Socialite\Facades\Socialite;
class SocialLoginController extends Controller
{
public function redirectToProvider(string $provider)
{
if (!in_array($provider, config('auth.socialite.drivers'), true)) {
abort(404, 'Social Provider is not supported');
}
return Socialite::driver($provider)->redirect();
}
}
routes/auth.php
use App\Http\Controllers\SocialLoginController;
// ...
Route::middleware('guest')->group(function () {
// ...
Route::post('login', [AuthenticatedSessionController::class, 'store']);
Route::get('redirect/{provider}', [SocialLoginController::class, 'redirectToProvider'])
->name('social.login')
->where('driver', implode('|', config('auth.socialite.drivers')));
// ...
});
// ...
resources/views/auth/login.blade.php
{{-- ... --}}
<x-primary-button-link
class="mr-2 ml-2"
:href="route('social.login', 'google')">
{{ __('Google Sign In') }}
</x-primary-button-link>
<x-primary-button>
{{ __('Log in') }}
</x-primary-button>
{{-- ... --}}
resources/views/auth/register.blade.php
{{-- ... --}}
<x-primary-button-link
class="mr-2 ml-2"
:href="route('social.login', 'google')">
{{ __('Google Sign In') }}
</x-primary-button-link>
<x-primary-button>
{{ __('Register') }}
</x-primary-button>
{{-- ... --}}
resources/views/components/primary-button-link.blade.php
<a {{ $attributes->merge(['class' => 'inline-flex items-center px-4 py-2 bg-gray-800 dark:bg-gray-200 border border-transparent rounded-md font-semibold text-xs text-white dark:text-gray-800 uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-white focus:bg-gray-700 dark:focus:bg-white active:bg-gray-900 dark:active:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150']) }}>
{{ $slot }}
</a>
app/Http/Controllers/SocialLoginController.php
use App\Models\User;
use Exception;
use Illuminate\Http\RedirectResponse;
use Laravel\Socialite\Facades\Socialite;
class SocialLoginController extends Controller
{
// ...
public function handleProviderCallback(string $provider): RedirectResponse
{
if (in_array($provider, config('auth.socialite.drivers'), true)) {
abort(404, 'Social Provider is not supported');
}
try {
$user = Socialite::driver($provider)->user();
} catch (Exception $e) {
return redirect()->route('login');
}
$existingUser = User::where('email', $user->getEmail())->first();
if ($existingUser) {
auth()->login($existingUser, true);
} else {
$newUser = new User;
$newUser->provider_name = $provider;
$newUser->provider_id = $user->getId();
$newUser->name = $user->getName();
$newUser->email = $user->getEmail();
$newUser->email_verified_at = now();
$newUser->avatar = $user->getAvatar();
$newUser->save();
auth()->login($newUser, true);
}
return redirect()->route('dashboard');
}
}
routes/auth.php
use App\Http\Controllers\SocialLoginController;
// ...
Route::middleware('guest')->group(function () {
// ...
Route::get('redirect/{provider}', [SocialLoginController::class, 'redirectToProvider'])
->name('social.login')
->where('driver', implode('|', config('auth.socialite.drivers')));
Route::get('{driver}/callback', [SocialLoginController::class, 'handleProviderCallback'])
->name('social.callback')
->where('driver', implode('|', config('auth.socialite.drivers')));
// ...
});
// ...
resources/views/layouts/navigation.blade.php
{{-- ... --}}
<div>
@if(auth()->user()->avatar)
<img src="{{ auth()->user()->avatar }}" alt="avatar" width="32" height="32"
class="mr-2 inline rounded"/>
@endif
{{ Auth::user()->name }}
</div>
{{-- ... --}}
<div class="font-medium text-base text-gray-800 dark:text-gray-200">
@if(auth()->user()->avatar)
<img src="{{ auth()->user()->avatar }}" alt="avatar" width="16" height="16"
class="mr-2 inline-block"/>
@endif
{{ Auth::user()->name }}
</div>
{{-- ... --}}
Kaynak:
https://laraveldaily.com/post/from-google-api-to-google-sign-in-with-laravel-socialite