Looking to hire Laravel developers? Try LaraJobs

sso-client-laravel maintained by mahulu

Description
Laravel package untuk integrasi dengan SSO Mahulu (OAuth 2.0 Authorization Code Flow)
Author
Last update
2026/04/28 14:12 (v1.1.2)
License
Links
Downloads
30

Comments
comments powered by Disqus

SSO Mahulu - Laravel Client Package

Package Laravel untuk integrasi OAuth 2.0 dengan SSO Mahulu (Identity Provider Pemerintah Mahulu Hulu)

Persyaratan

  • PHP >= 8.1
  • Laravel >= 10.x
  • OAuth Client Credentials dari admin SSO Mahulu

Instalasi

1. Install via Composer

# Dari Packagist (setelah di-publish)
composer require mahulu/sso-client-laravel

# Atau dari repository lokal/private
# Tambahkan di composer.json:
# "repositories": [
#     { "type": "vcs", "url": "https://github.com/your-org/sso-mahulu-laravel" }
# ]

2. Publish Config & Migration

# Publish config file
php artisan vendor:publish --tag=sso-mahulu-config

# Publish migration file
php artisan vendor:publish --tag=sso-mahulu-migrations

# Jalankan migration
php artisan migrate

3. Konfigurasi Environment

Tambahkan ke file .env:

SSO_MAHULU_BASE_URL=https://sso.mahulu.go.id
SSO_MAHULU_CLIENT_ID=your-client-id-dari-admin
SSO_MAHULU_CLIENT_SECRET=your-client-secret-dari-admin
SSO_MAHULU_REDIRECT_URI=https://your-app.mahulu.go.id/auth/sso/callback

Untuk development:

SSO_MAHULU_BASE_URL=http://sso-mahulu.test
SSO_MAHULU_REDIRECT_URI=http://your-app.test/auth/sso/callback

Cara Kerja

Package ini mengimplementasikan OAuth 2.0 Authorization Code Flow standar:

┌──────────────┐                          ┌──────────────┐
│  Aplikasi    │  1. Redirect ke SSO      │  SSO Mahulu  │
│  Anda        │ ───────────────────────> │  Server      │
│              │                          │              │
│              │  4. Callback + auth code │              │
│              │ <─────────────────────── │              │
│              │                          │              │
│              │  5. Exchange code->token │              │
│              │ ───────────────────────> │              │
│              │                          │              │
│              │  6. Access + Refresh     │              │
│              │ <─────────────────────── │              │
│              │                          │              │
│              │  7. GET /api/oauth/user  │              │
│              │ ───────────────────────> │              │
│              │                          │              │
│              │  8. User data            │              │
│              │ <─────────────────────── │              │
└──────────────┘                          └──────────────┘

Penjelasan Detail Alur (Step-by-Step)

  1. User klik tombol "Login SSO" → Aplikasi memanggil route sso.redirect
  2. Redirect ke SSO Server → Controller men-generate random state (disimpan di session sebagai CSRF protection), lalu redirect browser ke {SSO_BASE_URL}/oauth/authorize dengan parameter client_id, redirect_uri, response_type=code, scope, dan state
  3. User login di SSO → User memasukkan credentials di halaman login SSO Mahulu. Setelah berhasil, SSO server redirect balik ke redirect_uri aplikasi (route sso.callback) dengan membawa query parameter code (authorization code) dan state
  4. Exchange code → token → Aplikasi mengirim POST request ke {SSO_BASE_URL}/oauth/token berisi authorization_code, client_id, client_secret, dan redirect_uri. SSO server memvalidasi dan mengembalikan access_token, refresh_token, dan expires_in
  5. Ambil data user → Aplikasi menggunakan access_token untuk request GET ke {SSO_BASE_URL}/api/oauth/user dan mendapatkan data profil user dari SSO
  6. Simpan & login → Aplikasi mencari/membuat user di database lokal (berdasarkan user_identifier, default: nip), menyimpan token, lalu login user ke session Laravel
  7. Redirect ke dashboard → User diarahkan ke halaman redirect_after_login (default: /dashboard)

Proses Callback Secara Detail

Callback adalah inti dari proses autentikasi SSO. Ketika SSO server mengarahkan user kembali ke aplikasi Anda (route sso.callback), package menjalankan serangkaian validasi dan proses berikut:

1. Validasi State (CSRF Protection)

// Package otomatis memvalidasi parameter 'state'
// State di-generate saat redirect dan disimpan di session
// Jika state tidak cocok → redirect ke halaman error dengan pesan:
// "Invalid state parameter. Silakan coba login kembali."

Parameter state berfungsi sebagai CSRF protection untuk mencegah serangan cross-site request forgery. Saat user diarahkan ke SSO (step redirect), package men-generate string random 40 karakter dan menyimpannya di session. Saat callback, string ini dicocokkan dengan state yang dikirim balik oleh SSO. Jika tidak cocok (misalnya karena session expired atau manipulasi URL), proses login langsung dihentikan.

2. Deteksi Error dari SSO

// Jika SSO mengirimkan parameter 'error' di callback URL
// Contoh: /auth/sso/callback?error=access_denied&error_description=User+denied+access
// Package akan menampilkan pesan error_description ke user

SSO server dapat mengirimkan error di callback URL jika terjadi masalah (misal user menolak consent, atau client tidak valid). Package mendeteksi parameter error dan menampilkan error_description yang diberikan SSO.

3. Validasi Authorization Code

// Package memastikan parameter 'code' ada di callback URL
// Jika tidak ada → redirect ke halaman error dengan pesan:
// "Authorization code not found."

4. Exchange Authorization Code → Token

Package mengirimkan POST request ke endpoint SSO /oauth/token dengan payload:

POST {SSO_BASE_URL}/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
client_id={CLIENT_ID}
client_secret={CLIENT_SECRET}
redirect_uri={REDIRECT_URI}
code={AUTHORIZATION_CODE}

Jika berhasil, SSO mengembalikan response JSON:

{
  "token_type": "Bearer",
  "expires_in": 3600,
  "access_token": "eyJ0eXAiOiJKV1Q...",
  "refresh_token": "def5020089a5bfe7..."
}

5. Fetch Data User dari SSO

Menggunakan access_token yang didapat, package melakukan request:

GET {SSO_BASE_URL}/api/oauth/user
Authorization: Bearer {access_token}

Response berupa data user (lihat bagian User Data dari SSO).

6. Find or Create User Lokal

Package mencari user di database lokal berdasarkan kolom user_identifier (default: nip):

  • Jika auto_create_user = true → Gunakan updateOrCreate() untuk membuat user baru atau update user yang sudah ada
  • Jika auto_create_user = false → Hanya cari user yang sudah ada. Jika tidak ditemukan, lempar error: "User tidak ditemukan di sistem. Hubungi administrator."

Data yang disimpan/diupdate:

Field Sumber Keterangan
name ssoUser['name'] Nama lengkap dari SSO
email ssoUser['email'] Email dari SSO
sso_access_token tokens['access_token'] Disimpan jika store_tokens = true
sso_refresh_token tokens['refresh_token'] Disimpan jika store_tokens = true
token_expires_at now() + expires_in Waktu kadaluarsa access token

7. Login & Redirect

// Login user ke session Laravel dengan "remember me"
Auth::login($user, true);

// Regenerate session ID (security: mencegah session fixation)
$request->session()->regenerate();

// Redirect ke halaman yang diinginkan user, atau ke redirect_after_login
return redirect()->intended(config('sso-mahulu.redirect_after_login'));

Catatan: Method redirect()->intended() akan mengarahkan user ke halaman yang awalnya ingin diakses sebelum diarahkan ke login. Jika tidak ada halaman sebelumnya, user diarahkan ke redirect_after_login (default: /dashboard).

Penanganan Error di Callback

Package menangani dua jenis exception di callback:

Exception Penyebab Perilaku
SsoAuthenticationException Gagal exchange code, gagal fetch user, user tidak ditemukan Redirect ke redirect_on_error + tampilkan pesan error spesifik
\Exception (umum) Koneksi gagal, timeout, error tak terduga Redirect ke redirect_on_error + pesan: "Terjadi kesalahan saat login SSO" + log error

Penggunaan

Route yang Tersedia

Setelah install, route berikut otomatis terdaftar:

Method URI Name Fungsi
GET /auth/sso/redirect sso.redirect Redirect ke SSO login
GET /auth/sso/callback sso.callback Handle callback dari SSO
POST /auth/sso/logout sso.logout Logout & revoke token di SSO

Tambahkan Tombol Login di View

{{-- resources/views/login.blade.php --}}

{{-- Tombol Login SSO --}}
<a href="{{ route('sso.redirect') }}"
   class="btn btn-primary">
    Login dengan SSO Mahulu
</a>

Tambahkan Tombol Logout

<form method="POST" action="{{ route('sso.logout') }}">
    @csrf
    <button type="submit" class="btn btn-danger">
        Logout
    </button>
</form>

Menampilkan Error SSO

@if($errors->has('sso'))
    <div class="alert alert-danger">
        {{ $errors->first('sso') }}
    </div>
@endif

Integrasi dengan Laravel Inertia (Vue/React)

Jika Anda menggunakan Inertia.js, integrasi SSO memerlukan sedikit penyesuaian karena sifat Single Page Application (SPA). Berikut adalah panduan lengkapnya:

1. Tombol Login (PENTING)

Jangan gunakan component <Link> dari Inertia untuk tombol login. SSO memerlukan redirect penuh (full page visit) ke domain eksternal. Gunakan tag HTML <a> standar.

Vue.js / React:

<!-- Vue Example -->
<a href="/auth/sso/redirect" class="btn btn-primary">
  Login dengan SSO Mahulu
</a>

2. Tombol Logout

Logout juga memerlukan redirect ke server SSO. Karena endpoint /auth/sso/logout akan melakukan redirect ke domain luar (SSO), Request XHR (AJAX) dari Inertia mungkin akan mengalami masalah CORS atau error "Invalid JSON response".

Solusi 1 (Rekomendasi): Gunakan Form HTML Standar Gunakan form HTML biasa agar browser menangani redirect secara native.

<!-- Vue Example -->
<form action="/auth/sso/logout" method="POST">
  <!-- Sertakan CSRF Token jika framework tidak otomatis menanganinya di form manual -->
  <input type="hidden" name="_token" :value="$page.props.csrf_token">
  <button type="submit">Logout</button>
</form>

Solusi 2: Custom Controller dengan Inertia::location Jika Anda ingin menggunakan event handler (misal router.post), Anda perlu membuat Custom Controller yang mereturn Inertia::location alih-alih redirect biasa, atau biarkan Inertia menangani response. Namun, cara form standar di atas jauh lebih simpel dan stabil untuk kasus ini.

3. Menampilkan Error

Package ini mengirimkan pesan error menggunakan withErrors(['sso' => 'message']). Di Inertia, error ini otomatis tersedia di props errors.

Vue.js:

<template>
  <div v-if="$page.props.errors.sso" class="alert alert-danger">
    {{ $page.props.errors.sso }}
  </div>
</template>

React:

export default function Login({ errors }) {
  return (
    <>
      {errors.sso && <div className="alert alert-danger">{errors.sso}</div>}
      {/* ... */}
    </>
  );
}

4. Middleware & Shared Data

Pastikan middleware HandleInertiaRequests Anda membagikan data session yang diperlukan. Jika Anda menggunakan logic custom yang menggunakan Flash Message, pastikan itu dibagikan.

// app/Http/Middleware/HandleInertiaRequests.php
public function share(Request $request): array
{
    return array_merge(parent::share($request), [
        // Flash message sharing
        'flash' => [
            'message' => fn () => $request->session()->get('message'),
            'error'   => fn () => $request->session()->get('error'),
        ],
        // Errors sudah otomatis dibagikan oleh Inertia
    ]);
}

Auto-Refresh Token (Middleware)

Package menyediakan middleware sso.token (EnsureSsoTokenValid) yang otomatis me-refresh expired access token secara transparan di setiap request. User tidak perlu login ulang selama refresh token masih valid.

Cara Registrasi Middleware:

// app/Http/Kernel.php (Laravel 10)
// atau bootstrap/app.php (Laravel 11+)

// Di route group:
Route::middleware(['auth', 'sso.token'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    // ... route lainnya
});

Cara Kerja Middleware sso.token:

  1. Cek apakah user sudah login → jika belum, skip (lanjut ke request berikutnya)
  2. Cek apakah store_tokens diaktifkan di config → jika tidak, skip
  3. Cek apakah token_expires_at sudah lewat → jika belum expired, skip
  4. Jika token expired:
    • Jika refresh token tersedia → kirim request ke SSO untuk mendapatkan access token baru, update database
    • Jika refresh token tidak tersedia → logout user, redirect ke halaman error dengan pesan "Session Anda telah expired"
    • Jika refresh gagal (token revoked/expired/server error) → logout user, redirect ke halaman error

Penting: Refresh token memiliki masa berlaku 14 hari. Setelah 14 hari tanpa aktivitas, user harus login ulang ke SSO.

Menggunakan SsoService Langsung

Jika perlu mengakses SSO API secara manual:

use Mahulu\SsoClient\Services\SsoService;
// atau via Facade:
use Mahulu\SsoClient\Facades\SsoMahulu;

class MyController extends Controller
{
    public function someAction(SsoService $sso)
    {
        // Check apakah token user expired
        $user = auth()->user();

        if ($sso->isTokenExpired($user->token_expires_at)) {
            // Refresh token
            $newTokens = $sso->refreshToken($user->sso_refresh_token);

            $user->update([
                'sso_access_token'  => $newTokens['access_token'],
                'sso_refresh_token' => $newTokens['refresh_token'],
                'token_expires_at'  => now()->addSeconds($newTokens['expires_in']),
            ]);
        }

        // Ambil user info terbaru dari SSO
        $ssoUser = $sso->getUserInfo($user->sso_access_token);
    }

    // Via Facade
    public function viaFacade()
    {
        $user = SsoMahulu::getUserInfo(auth()->user()->sso_access_token);
    }
}

Konfigurasi Lengkap

File config config/sso-mahulu.php:

Key ENV Variable Default Deskripsi
base_url SSO_MAHULU_BASE_URL https://sso.mahulu.go.id URL server SSO
client_id SSO_MAHULU_CLIENT_ID - OAuth Client ID
client_secret SSO_MAHULU_CLIENT_SECRET - OAuth Client Secret
redirect_uri SSO_MAHULU_REDIRECT_URI - Callback URL
scopes SSO_MAHULU_SCOPES '' OAuth scopes
route_prefix SSO_MAHULU_ROUTE_PREFIX auth/sso Prefix route SSO
route_middleware - ['web'] Middleware group untuk route SSO
redirect_after_login SSO_MAHULU_REDIRECT_AFTER_LOGIN /dashboard Path setelah login sukses
redirect_after_logout SSO_MAHULU_REDIRECT_AFTER_LOGOUT / Path setelah logout
redirect_on_error SSO_MAHULU_REDIRECT_ON_ERROR /login Path saat error
user_model SSO_MAHULU_USER_MODEL App\Models\User Class model User
user_identifier SSO_MAHULU_USER_IDENTIFIER nip Kolom identifier user
auto_create_user SSO_MAHULU_AUTO_CREATE_USER true Auto-create user baru saat login SSO
store_tokens SSO_MAHULU_STORE_TOKENS true Simpan token di DB
timeout SSO_MAHULU_TIMEOUT 30 HTTP timeout (detik)

Database Migration

Migration yang di-publish akan menambahkan kolom berikut ke tabel users:

Kolom Tipe Nullable Deskripsi
nip string Yes Nomor Induk Pegawai (unique)
sso_access_token text Yes Access token dari SSO
sso_refresh_token text Yes Refresh token dari SSO
token_expires_at timestamp Yes Waktu expiry access token

Pastikan model User memiliki kolom-kolom ini di $fillable:

// app/Models/User.php
class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',
        'nip',                 // Tambahkan
        'sso_access_token',    // Tambahkan
        'sso_refresh_token',   // Tambahkan
        'token_expires_at',    // Tambahkan
    ];

    protected $hidden = [
        'password',
        'remember_token',
        'sso_access_token',    // Sembunyikan dari JSON/Array
        'sso_refresh_token',   // Sembunyikan dari JSON/Array
    ];

    protected $casts = [
        'token_expires_at' => 'datetime', // Cast ke Carbon
    ];
}

User Data dari SSO

Setelah login berhasil, data berikut tersedia dari SSO:

{
  "id": 1,
  "nip": "199001012020121001",
  "name": "Budi Santoso",
  "email": "budi.santoso@mahulu.go.id",
  "username": "199001012020121001",
  "is_active": true,
  "api_hub_data": {
    "jabatan": "Kepala Bidang Kepegawaian",
    "unit_kerja": "Badan Kepegawaian Daerah",
    "pangkat_golongan": "Pembina (IV/a)",
    "eselon": "III/a"
  },
  "created_at": "2026-01-25T10:30:00.000000Z",
  "updated_at": "2026-01-25T10:30:00.000000Z"
}

Kustomisasi

Custom Callback Logic

Jika perlu kustomisasi proses callback (misal: assign role, sync data tambahan), override controller:

// app/Http/Controllers/Auth/CustomSsoController.php
namespace App\Http\Controllers\Auth;

use Mahulu\SsoClient\Controllers\SsoAuthController;
use Mahulu\SsoClient\Exceptions\SsoAuthenticationException;

class CustomSsoController extends SsoAuthController
{
    protected function findOrCreateUser(array $ssoUser, array $tokens)
    {
        // Panggil parent untuk logic default
        $user = parent::findOrCreateUser($ssoUser, $tokens);

        // Tambahan: assign role berdasarkan data SSO
        if (!$user->hasRole('pegawai')) {
            $user->assignRole('pegawai');
        }

        // Tambahan: sync data dari api_hub_data
        if (isset($ssoUser['api_hub_data'])) {
            $user->update([
                'jabatan'    => $ssoUser['api_hub_data']['jabatan'] ?? null,
                'unit_kerja' => $ssoUser['api_hub_data']['unit_kerja'] ?? null,
            ]);
        }

        return $user;
    }
}

Kemudian override route di routes/web.php:

use App\Http\Controllers\Auth\CustomSsoController;

// Override route SSO (taruh SEBELUM package routes ter-load)
Route::get('auth/sso/redirect', [CustomSsoController::class, 'redirect'])->name('sso.redirect');
Route::get('auth/sso/callback', [CustomSsoController::class, 'callback'])->name('sso.callback');
Route::post('auth/sso/logout', [CustomSsoController::class, 'logout'])->name('sso.logout');

Custom Route Prefix

SSO_MAHULU_ROUTE_PREFIX=login/sso

Routes menjadi: /login/sso/redirect, /login/sso/callback, /login/sso/logout

Disable Auto-Create User

Jika hanya ingin user yang sudah terdaftar yang bisa login:

SSO_MAHULU_AUTO_CREATE_USER=false

Token Expiration

Token Durasi Keterangan
Access Token 60 menit Untuk akses API SSO
Refresh Token 14 hari Untuk mendapatkan access token baru
Authorization Code 10 menit Hanya bisa dipakai 1x

Mendapatkan OAuth Client Credentials

  1. Hubungi admin SSO Mahulu di admin-sso@mahulu.go.id
  2. Sertakan informasi:
    • Nama aplikasi
    • Redirect URI (development & production)
    • PIC (nama & kontak)
  3. Admin akan mendaftarkan aplikasi dan mengirimkan CLIENT_ID & CLIENT_SECRET

PENTING:

  • CLIENT_SECRET hanya ditampilkan SATU KALI. Simpan dengan aman.
  • Jangan commit credentials ke Git repository.
  • Gunakan environment variables.

Troubleshooting

Error: "Invalid state parameter"

  • Session mungkin expired. Coba login ulang.
  • Pastikan SESSION_DRIVER dikonfigurasi dengan benar.

Error: "Failed to exchange authorization code"

  • Pastikan SSO_MAHULU_CLIENT_ID dan SSO_MAHULU_CLIENT_SECRET benar.
  • Pastikan SSO_MAHULU_REDIRECT_URI match persis dengan yang didaftarkan.
  • Pastikan SSO server dapat diakses dari aplikasi Anda.

Error: "User identifier 'nip' not found in SSO response"

  • Pastikan migration sudah dijalankan dan kolom nip ada di tabel users.
  • Pastikan kolom nip ada di $fillable model User.

Error: "Session expired"

  • Token SSO sudah expired dan refresh gagal.
  • User perlu login ulang.

CORS Error

  • Pastikan domain aplikasi Anda sudah ditambahkan di konfigurasi CORS server SSO.
  • Untuk development, domain .test biasanya sudah diizinkan.

API Reference

SsoService

Class utama untuk berinteraksi dengan SSO server. Tersedia melalui Dependency Injection atau Facade.

// Via Dependency Injection
use Mahulu\SsoClient\Services\SsoService;

public function myMethod(SsoService $sso) { ... }

// Via Facade
use Mahulu\SsoClient\Facades\SsoMahulu;

SsoMahulu::getUserInfo($token);

Method yang Tersedia

Method Parameter Return Deskripsi
getAuthorizationUrl(string $state) $state — random string untuk CSRF protection string — full URL authorization Membuat URL untuk redirect ke halaman login SSO
exchangeCodeForToken(string $code) $code — authorization code dari callback array{token_type, expires_in, access_token, refresh_token} Menukar authorization code dengan access token & refresh token
getUserInfo(string $accessToken) $accessToken — access token yang valid array — data user (lihat User Data dari SSO) Mengambil informasi user dari SSO server
refreshToken(string $refreshToken) $refreshToken — refresh token yang valid array{token_type, expires_in, access_token, refresh_token} Mendapatkan access token baru menggunakan refresh token
getLogoutUrl() - string — URL logout SSO Mendapatkan URL untuk logout di SSO server
isTokenExpired(?DateTimeInterface $expiresAt) $expiresAt — waktu kadaluarsa token booltrue jika sudah expired Mengecek apakah token sudah kadaluarsa

Catatan: Semua method yang berkomunikasi dengan SSO server (exchange, getUserInfo, refreshToken) akan melempar SsoAuthenticationException jika terjadi error.

SsoAuthenticationException

Exception khusus yang dilempar oleh package saat proses autentikasi SSO gagal.

use Mahulu\SsoClient\Exceptions\SsoAuthenticationException;

try {
    $tokens = $sso->exchangeCodeForToken($code);
} catch (SsoAuthenticationException $e) {
    $message    = $e->getMessage();    // Pesan error
    $httpStatus = $e->getHttpStatus(); // HTTP status code dari SSO (0 jika koneksi gagal)
}

Kondisi yang memicu exception ini:

Kondisi Pesan
Gagal menukar authorization code "Failed to exchange authorization code for access token."
Gagal mengambil data user "Failed to retrieve user information from SSO."
Gagal refresh token "Failed to refresh access token."
Koneksi ke SSO gagal (timeout, DNS error, dll) "Connection to SSO server failed: {detail error}"
User identifier tidak ditemukan di response SSO "User identifier '{field}' not found in SSO response."
User tidak ditemukan di DB (jika auto_create_user = false) "User tidak ditemukan di sistem. Hubungi administrator."

Proses Logout Secara Detail

Ketika user menekan tombol logout, package melakukan:

  1. Logout session LaravelAuth::logout() menghapus session autentikasi
  2. Invalidasi session$request->session()->invalidate() menghapus seluruh data session
  3. Regenerasi CSRF token$request->session()->regenerateToken() untuk keamanan
  4. Redirect ke SSO logout — Browser diarahkan ke {SSO_BASE_URL}/oauth/logout untuk mencabut token di sisi SSO server

Catatan: Logout di sisi SSO juga akan menghapus session SSO, sehingga user harus login ulang di SSO jika ingin mengakses aplikasi manapun yang menggunakan SSO Mahulu.

Security

State Parameter (CSRF Protection)

Package secara otomatis men-generate dan memvalidasi state parameter di setiap proses login. Ini mencegah serangan Cross-Site Request Forgery di mana penyerang mencoba mengarahkan user ke callback URL palsu.

Session Regeneration

Setelah login berhasil, session ID di-regenerasi ($request->session()->regenerate()) untuk mencegah serangan Session Fixation.

Token Storage Security

  • Access token dan refresh token disimpan di database (kolom sso_access_token dan sso_refresh_token)
  • Kedua kolom ini harus ditambahkan ke $hidden di model User agar tidak bocor di response JSON/API
  • Token tidak pernah dikirimkan ke browser/frontend

Best Practices

  • Jangan commit CLIENT_SECRET ke repository — gunakan environment variable
  • Gunakan HTTPS di production — agar token tidak terekspos saat transit
  • Pastikan redirect_uri match persis dengan yang didaftarkan di admin SSO — perbedaan satu karakter pun akan ditolak oleh SSO server
  • Monitor log — Package mencatat semua error autentikasi ke Laravel log dengan prefix [SSO Mahulu]

Struktur Package

sso-mahulu-laravel/
├── composer.json
├── README.md
├── .gitignore
├── config/
│   └── sso-mahulu.php              # Config file (publishable)
├── database/
│   └── migrations/
│       └── add_sso_columns_to_users_table.php  # Migration (publishable)
├── routes/
│   └── sso.php                     # Route definitions
└── src/
    ├── SsoClientServiceProvider.php # Service Provider (auto-discovery)
    ├── Controllers/
    │   └── SsoAuthController.php    # OAuth flow controller
    ├── Exceptions/
    │   └── SsoAuthenticationException.php  # Custom exception class
    ├── Facades/
    │   └── SsoMahulu.php            # Facade (shortcut ke SsoService)
    ├── Middleware/
    │   └── EnsureSsoTokenValid.php   # Auto-refresh token middleware
    └── Services/
        └── SsoService.php           # Core SSO service (HTTP calls)

Lisensi

MIT License

Support