File size: 5,211 Bytes
74acf19 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | <?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'));
}
}
|