Laravel (Socialite)
Laravel punya package Composer khusus (sso-frappe-laravel) yang dibangun di atas Laravel Socialite. PHP tidak bisa import package npm, jadi provider Laravel didistribusi via Composer/Packagist.
Requirements
- PHP
^8.2 - Laravel
^11.0|^12.0 - Laravel Socialite
^5.0
Install
composer require sso-frappe/laravelKonfigurasi
php artisan vendor:publish --tag=sso-frappe-configFRAPPE_SSO_BASE_URL=https://erp.example.com
FRAPPE_SSO_CLIENT_ID=<oauth-client-id>
FRAPPE_SSO_CLIENT_SECRET=<oauth-client-secret>
FRAPPE_SSO_REDIRECT_URI=https://app.example.com/auth/frappe/callbackRoutes
// routes/web.php
use Laravel\Socialite\Facades\Socialite;
Route::get('/auth/frappe', fn () =>
Socialite::driver('frappe')->redirect()
)->name('frappe.login');
Route::get('/auth/frappe/callback', function () {
$frappeUser = Socialite::driver('frappe')->user();
// Cocokkan/buat user lokal (lihat panduan schema di bawah)
$identity = \App\Models\UserIdentity::query()
->where('provider', 'frappe')
->where('provider_subject', $frappeUser->getId())
->first();
// ... link by email, atau buat users + user_identities, lalu Auth::login()
})->name('frappe.callback');Contoh controller
// app/Http/Controllers/FrappeLoginController.php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\UserIdentity;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Laravel\Socialite\Facades\Socialite;
class FrappeLoginController extends Controller
{
public function __invoke()
{
$frappe = Socialite::driver('frappe')->user();
$user = DB::transaction(function () use ($frappe) {
// Subject first
$identity = UserIdentity::query()
->where('provider', 'frappe')
->where('provider_subject', $frappe->getId())
->first();
if ($identity) {
return $identity->user;
}
// Email fallback — link user manual yang sudah ada
$user = User::query()->firstOrCreate(
['email' => strtolower($frappe->getEmail())],
[
'name' => $frappe->getName(),
'password' => null,
'status' => 'AKTIF',
],
);
$user->identities()->create([
'provider' => 'frappe',
'provider_subject' => $frappe->getId(),
'provider_email' => strtolower($frappe->getEmail()),
'metadata' => [
'roles' => $frappe->frappe_roles ?? [],
],
]);
return $user;
});
abort_unless($user->status === 'AKTIF', 403);
Auth::login($user, remember: true);
request()->session()->regenerate();
return redirect()->intended('/dashboard');
}
}Field profile
| Property | Source | Keterangan |
|---|---|---|
getId() |
sub |
Stable subject ID — kunci identitas |
getEmail() |
email |
|
getName() |
name |
Nama lengkap |
getNickname() |
username |
Username Frappe |
getAvatar() |
user_image |
URL avatar |
frappe_roles |
roles |
Array role |
getRaw() |
— | Raw userinfo array |
Yang di-handle otomatis
client_secret_post— Socialite kirim kredensial di POST body (sesuai Frappe)- PKCE S256 (aktif default, nonaktif via
use_pkce => false) - Endpoint eksplisit — tanpa dependency OIDC discovery
- Normalisasi profile
Schema
Lihat database schema — schema identitas yang direkomendasikan berlaku untuk JS dan Laravel.