PHP (Laravel)
Contoh integrasi OAuth dengan Laravel.
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\OAuthController;
Route::get('/login', [OAuthController::class, 'login'])->name('oauth.login');
Route::get('/callback', [OAuthController::class, 'callback'])->name('oauth.callback');
Route::post('/refresh', [OAuthController::class, 'refresh'])->name('oauth.refresh');<?php
// app/Http/Controllers/OAuthController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Session;
class OAuthController extends Controller
{
// Konfigurasi
private string $clientId = 'YOUR_CLIENT_ID';
private string $clientSecret = 'YOUR_CLIENT_SECRET';
private string $redirectUri = 'http://localhost:8000/callback';
private string $authServerUrl; // Origin (tanpa /api/auth)
private string $issuer; // Issuer OIDC (.../api/auth)
private array $scopes = ['openid', 'profile', 'email', 'role', 'organization'];
public function __construct()
{
$this->authServerUrl = 'https://bukutamu.tabalongkab.go.id';
$this->issuer = 'https://bukutamu.tabalongkab.go.id/api/auth';
}
/**
* Generate code verifier untuk PKCE
*/
private function generateCodeVerifier(): string
{
return Str::random(64);
}
/**
* Generate code challenge dari code verifier (S256)
*/
private function generateCodeChallenge(string $codeVerifier): string
{
$hash = hash('sha256', $codeVerifier, true);
return rtrim(strtr(base64_encode($hash), '+/', '-_'), '=');
}
/**
* Mulai OAuth flow
*/
public function login()
{
// Generate PKCE values
$codeVerifier = $this->generateCodeVerifier();
$codeChallenge = $this->generateCodeChallenge($codeVerifier);
$state = Str::random(32);
// Simpan untuk verifikasi nanti
Session::put('oauth_state', $state);
Session::put('code_verifier', $codeVerifier);
// Buat authorization URL
$authParams = http_build_query([
'client_id' => $this->clientId,
'redirect_uri' => $this->redirectUri,
'response_type' => 'code',
'scope' => implode(' ', $this->scopes),
'state' => $state,
'code_challenge' => $codeChallenge,
'code_challenge_method' => 'S256',
]);
$authUrl = "{$this->authServerUrl}/api/auth/oauth2/authorize?{$authParams}";
// Redirect user ke SSO Tabalong
return redirect($authUrl);
}
/**
* Handle OAuth callback
*/
public function callback(Request $request)
{
// Handle error dari OAuth server
if ($request->has('error')) {
return response()->json([
'error' => $request->get('error'),
'error_description' => $request->get('error_description'),
], 400);
}
$code = $request->get('code');
$state = $request->get('state');
// Verifikasi state
if ($state !== Session::get('oauth_state')) {
return response()->json(['error' => 'Invalid state parameter'], 400);
}
$codeVerifier = Session::get('code_verifier');
// Bersihkan session
Session::forget(['oauth_state', 'code_verifier']);
// Tukar code dengan token
$tokenResponse = Http::asForm()->post(
"{$this->authServerUrl}/api/auth/oauth2/token",
[
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => $this->redirectUri,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'code_verifier' => $codeVerifier,
]
);
if (!$tokenResponse->successful()) {
return response()->json($tokenResponse->json(), 400);
}
$tokens = $tokenResponse->json();
// Ambil user info
$userInfoResponse = Http::withToken($tokens['access_token'])
->get("{$this->authServerUrl}/api/auth/oauth2/userinfo");
$userInfo = $userInfoResponse->json();
// Simpan di session
Session::put('user', $userInfo);
Session::put('tokens', $tokens);
return response()->json([
'tokens' => $tokens,
'userinfo' => $userInfo,
]);
}
/**
* Refresh access token
*/
public function refresh(Request $request)
{
$refreshToken = $request->input('refresh_token');
$response = Http::asForm()->post(
"{$this->authServerUrl}/api/auth/oauth2/token",
[
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
]
);
return response()->json($response->json());
}
}