Laravel / PHP
The squareexp/base-idp Composer package — confidential server login and token verification for Laravel applications.
The Laravel package wraps Base IdP for PHP applications. It runs the login, exchanges the code, verifies tokens, and exposes the current user through guards and middleware. It is the right tool for server-rendered PHP apps that authenticate users themselves.
If your PHP app is a pure API behind a mobile or SPA frontend, you only need the verifier — no secret required. The package supports both shapes.
Install
composer require squareexp/base-idpThe package targets Laravel 10 and 11. It also works in a plain PHP application; the framework integration is optional.
Publish the config
php artisan vendor:publish --provider="Squareexp\BaseIdp\BaseIdpServiceProvider"This publishes config/base-idp.php where you control timeouts, the
expected scopes, and the default redirect path.
Configure
BASE_IDP_CLIENT_ID=sq_live_yourapp
BASE_IDP_CLIENT_SECRET=sqk_your_secretThe secret is server-side only. Keep .env out of version control.
The login routes
Wire two routes — one to start the flow, one to handle the callback.
use Squareexp\BaseIdp\Http\Controllers\BaseIdpController;
Route::get('/auth/login', [BaseIdpController::class, 'login'])->name('auth.login');
Route::get('/auth/callback', [BaseIdpController::class, 'callback'])->name('auth.callback');The default callback handler signs the user into Laravel's session guard and
redirects to /. Override the controller to do something different.
Custom callback handling
use Squareexp\BaseIdp\Facades\BaseIdp;
class AuthController extends Controller
{
public function callback(Request $request)
{
$tokens = BaseIdp::exchangeCode($request->query('code'));
$principal = BaseIdp::verify($tokens['access_token']);
$user = User::updateOrCreate(
['idp_subject' => $principal['sub']],
[
'email' => $principal['email'],
'name' => $principal['name'],
],
);
Auth::login($user);
return redirect()->intended('/dashboard');
}
}Verifying tokens
For an API that only verifies incoming tokens:
use Squareexp\BaseIdp\Facades\BaseIdp;
$principal = BaseIdp::verify($bearerToken);
// [
// 'sub' => 'usr_01HRZ...',
// 'gid' => 'gid_01HRZ...',
// 'email' => 'user@example.com',
// 'name' => 'Ajmal Leonard',
// 'scopes' => ['openid', 'profile'],
// ]Middleware
The package ships a route middleware:
Route::middleware('base-idp')->group(function () {
Route::get('/me', function (Request $request) {
return response()->json($request->attributes->get('principal'));
});
});The middleware reads the Authorization: Bearer header, verifies the token,
and attaches the principal to the request.
Auth guard
For server-rendered apps the package registers a guard you can wire into
config/auth.php.
'guards' => [
'base-idp' => [
'driver' => 'base-idp',
'provider' => 'users',
],
],Use it the same way you use any other guard:
Auth::guard('base-idp')->user();Refresh
$tokens = BaseIdp::refresh($refreshToken);Store the new refresh token. The old one is invalidated as soon as you call this.
Logout
BaseIdp::logout($refreshToken);
Auth::guard('base-idp')->logout();The first call revokes the session on Base IdP. The second clears Laravel's session.
A complete fullstack flow
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Squareexp\BaseIdp\Facades\BaseIdp;
use App\Models\User;
class AuthController extends Controller
{
public function login()
{
return redirect(BaseIdp::authorizeUrl([
'state' => session('return_to', '/'),
]));
}
public function callback(Request $request)
{
$tokens = BaseIdp::exchangeCode($request->query('code'));
$principal = BaseIdp::verify($tokens['access_token']);
$user = User::updateOrCreate(
['idp_subject' => $principal['sub']],
[
'email' => $principal['email'],
'name' => $principal['name'],
],
);
Auth::login($user);
return redirect($request->query('state', '/dashboard'));
}
public function logout(Request $request)
{
$refresh = session('base_idp_refresh');
if ($refresh) {
BaseIdp::logout($refresh);
}
Auth::logout();
return redirect('/');
}
}A complete confidential-server login in one controller. Add the routes, publish the config, set the two env values, and the app is integrated.
Where to go next
Swift / SwiftUI
The BaseIdP Swift package — native PKCE login for SwiftUI apps on iOS, iPadOS, macOS, Mac Catalyst, and visionOS, with a Keychain-backed session and a server-handoff helper.
Overview
Copy-paste Base IdP integration walkthroughs for every supported stack. Pick the one that matches your code.