teknolis / app /Http /Controllers /Auth /GoogleAuthController.php
Codex
Deploy latest assistant, DeepSeek defaults, and automation updates
74acf19
Raw
History Blame Contribute Delete
5.21 kB
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
class GoogleAuthController extends Controller
{
public function redirect(Request $request): RedirectResponse
{
if (! $this->isGoogleLoginConfigured()) {
return redirect()->route('login')->withErrors([
'google' => 'Login Google belum dikonfigurasi. Isi GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, dan GOOGLE_REDIRECT_URI terlebih dulu.',
]);
}
$state = Str::random(40);
$request->session()->put('google_oauth_state', $state);
$query = http_build_query([
'client_id' => (string) config('services.google.client_id'),
'redirect_uri' => (string) config('services.google.redirect'),
'response_type' => 'code',
'scope' => 'openid profile email',
'prompt' => 'select_account',
'access_type' => 'offline',
'state' => $state,
]);
return redirect()->away('https://accounts.google.com/o/oauth2/v2/auth?'.$query);
}
public function callback(Request $request): RedirectResponse
{
$storedState = (string) $request->session()->pull('google_oauth_state', '');
$returnedState = (string) $request->string('state');
if ($request->filled('error')) {
return redirect()->route('login')->withErrors([
'google' => 'Login Google dibatalkan atau ditolak oleh pengguna.',
]);
}
if ($storedState === '' || ! hash_equals($storedState, $returnedState)) {
return redirect()->route('login')->withErrors([
'google' => 'Sesi login Google tidak valid. Coba ulangi lagi.',
]);
}
if (! $this->isGoogleLoginConfigured()) {
return redirect()->route('login')->withErrors([
'google' => 'Login Google belum dikonfigurasi di server.',
]);
}
$tokenResponse = Http::asForm()
->timeout(20)
->post('https://oauth2.googleapis.com/token', [
'code' => (string) $request->string('code'),
'client_id' => (string) config('services.google.client_id'),
'client_secret' => (string) config('services.google.client_secret'),
'redirect_uri' => (string) config('services.google.redirect'),
'grant_type' => 'authorization_code',
]);
if (! $tokenResponse->ok() || ! $tokenResponse->json('access_token')) {
return redirect()->route('login')->withErrors([
'google' => 'Google tidak mengembalikan access token yang valid.',
]);
}
$googleProfile = Http::withToken((string) $tokenResponse->json('access_token'))
->timeout(20)
->get('https://openidconnect.googleapis.com/v1/userinfo');
if (! $googleProfile->ok()) {
return redirect()->route('login')->withErrors([
'google' => 'Profil akun Google tidak bisa diambil saat ini.',
]);
}
$profile = $googleProfile->json();
$googleId = trim((string) data_get($profile, 'sub', ''));
$email = Str::lower(trim((string) data_get($profile, 'email', '')));
if ($googleId === '' || $email === '') {
return redirect()->route('login')->withErrors([
'google' => 'Data akun Google tidak lengkap. Pastikan email tersedia di akun Google Anda.',
]);
}
$user = User::query()
->where('google_id', $googleId)
->orWhere('email', $email)
->first();
if (! $user) {
$user = User::create([
'name' => trim((string) data_get($profile, 'name', Str::before($email, '@'))),
'email' => $email,
'google_id' => $googleId,
'email_verified_at' => data_get($profile, 'email_verified') ? Carbon::now() : null,
'password' => Hash::make(Str::random(40)),
]);
} else {
$user->forceFill([
'name' => $user->name ?: trim((string) data_get($profile, 'name', Str::before($email, '@'))),
'google_id' => $user->google_id ?: $googleId,
]);
if (! $user->email_verified_at && data_get($profile, 'email_verified')) {
$user->email_verified_at = Carbon::now();
}
$user->save();
}
Auth::login($user, true);
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
private function isGoogleLoginConfigured(): bool
{
return filled(config('services.google.client_id'))
&& filled(config('services.google.client_secret'))
&& filled(config('services.google.redirect'));
}
}