sso-laravel maintained by gorontalokota
gorontalokota/sso-laravel
Login SSO Pemerintah Kota Gorontalo untuk Laravel 12–13 (PHP 8.2+): route siap pakai, penautan akun lokal, back-channel logout otomatis, dan guard API bearer token.
Instalasi
composer require gorontalokota/sso-laravel
php artisan sso:install # publikasikan config + migrasi, tampilkan URI untuk didaftarkan
php artisan migrate # menambah kolom users.sso_sub
.env:
SSO_REALM=internal # internal (ASN) atau external (masyarakat)
SSO_CLIENT_ID=internal-xxxx
SSO_CLIENT_SECRET=xxxx
SSO_SCOPES="openid profile email asn"
Daftarkan di portal pengembang SSO (perintah sso:install menampilkan nilainya):
- Redirect URI:
{APP_URL}/sso/callback - Back-channel logout URI:
{APP_URL}/sso/backchannel-logout - Post logout redirect URI:
{APP_URL}/
Login di aplikasi web
Tombol masuk dan keluar:
<a href="{{ route('sso.login') }}">Masuk dengan SSO</a>
<form method="POST" action="{{ route('sso.logout') }}">
@csrf
<button type="submit">Keluar</button>
</form>
@if (session('sso_error'))
<p role="alert">{{ session('sso_error') }}</p>
@endif
Arahkan tamu yang membuka halaman ber-middleware auth ke SSO (bootstrap/app.php, Laravel 11+):
->withMiddleware(function (Middleware $middleware) {
$middleware->redirectGuestsTo(fn () => route('sso.login'));
})
Setelah login, pengguna lokal tersedia lewat auth()->user() seperti biasa. Data SSO-nya lewat facade:
use Gorontalokota\Sso\Laravel\Facades\Sso;
Sso::user()->nip(); // NIP (realm internal)
Sso::user()->employment(); // OPD, jabatan, golongan (scope asn)
Sso::accessToken(); // untuk memanggil API lain yang dilindungi SSO, diperbarui otomatis
Menautkan akun lokal
Atur di config/sso.php:
'user' => [
'model' => App\Models\User::class,
'sub_column' => 'sso_sub',
'match_by' => ['nip' => 'nip'], // akun lama dicocokkan SEKALI lewat NIP, lalu disimpan sub-nya
'create' => false, // true: buat akun baru untuk pengguna SSO yang belum ada
'sync' => ['name' => 'name'], // kolom yang diperbarui dari SSO setiap login
],
Untuk aturan sendiri (mis. hanya pegawai OPD tertentu), buat kelas yang mengimplementasikan Gorontalokota\Sso\Laravel\Contracts\UserResolver dan isi sso.user.resolver. Kembalikan null untuk menolak akses.
Event yang tersedia: SsoAuthenticated (setelah login) dan SsoSessionEnded (back-channel logout).
Back-channel logout
Aktif otomatis. Middleware ditambahkan ke grup web sehingga pengguna yang sesinya diakhiri SSO langsung keluar pada request berikutnya. Gunakan cache bersama (Redis/database) bila aplikasi berjalan di lebih dari satu server: SSO_CACHE_STORE=redis.
Frontend Vue / Inertia (BFF)
GET /sso/user mengembalikan JSON pengguna aktif (401 bila belum login). Pakai bersama useSso() dari paket npm @gorontalokota/sso/vue. Token tetap di server.
API dengan bearer token (seperti keycloak-guard)
config/auth.php:
'guards' => [
'api' => ['driver' => 'sso', 'provider' => 'users'],
],
Route::middleware('auth:api')->get('/profil', fn () => auth('api')->user());
Route::middleware(['auth:api', 'sso.scope:asn'])->get('/kepegawaian', ...);
SSO_API_AUDIENCES: client_id yang tokennya diterima API ini (dipisah koma). Bawaan: client_id aplikasi ini.sso.api.load_user = true:auth('api')->user()adalah model lokal (dicari lewatsso_sub). Bilafalse, isinyaTokenUserberisi klaim token.- Klaim token:
$request->attributes->get('sso_token')(AccessTokenClaims).
Pengujian
use Gorontalokota\Sso\Laravel\SsoServiceProvider;
use Gorontalokota\Sso\Testing\FakeProvider;
$provider = new FakeProvider('https://sso.test/internal', 'client-tes');
config(['sso.issuer' => $provider->issuer, 'sso.client_id' => $provider->clientId]);
app()->instance(SsoServiceProvider::HTTP_CLIENT, $provider->http());
$this->withToken($provider->accessToken())->getJson('/api/profil')->assertOk();