gorontalokota / sso-laravel
Integrasi SSO Pemerintah Kota Gorontalo untuk Laravel: login OIDC siap pakai, back-channel logout, dan guard API bearer token.
Package info
github.com/Diskominfo-Kota-Gorontalo/sso-laravel
pkg:composer/gorontalokota/sso-laravel
Requires
- php: ^8.2
- gorontalokota/sso-php: ^0.1
- illuminate/auth: ^12.0 || ^13.0
- illuminate/cache: ^12.0 || ^13.0
- illuminate/http: ^12.0 || ^13.0
- illuminate/routing: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
Requires (Dev)
- orchestra/testbench: ^10.0 || ^11.0
- phpunit/phpunit: ^11.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-11-09 10:44:54 UTC
README
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();