Appearance
OAuth Server
OAuth server mode is optional and disabled by default. It is for third-party clients, consent, and integration APIs.
OAuth server tokens use separate sp_oauth_* tables and sp.oauth middleware. They do not share first-party sp_jwt_* token storage.
Enable OAuth Server Mode
env
SP_JWT_OAUTH_SERVER_ENABLED=trueRoutes are registered under oauth_server.route_prefix, default oauth.
Create a Client
php
use Sopheak\JwtAuth\DTO\OAuthClientData;
use Sopheak\JwtAuth\Services\OAuthClientRepository;
$secret = app(OAuthClientRepository::class)->createClient(new OAuthClientData(
name: 'ERP Connector',
redirectUris: ['https://client.example/callback'],
allowedGrants: ['authorization_code', 'refresh_token'],
allowedScopes: ['invoices.read'],
));Confidential client secrets are returned once and stored as HMAC hashes.
Authorization Code + PKCE
Validate the incoming authorization request:
php
$authorization = app(OAuthServerService::class)
->validateAuthorizationRequest($request);After the app-owned consent UI approves access:
php
use Sopheak\JwtAuth\DTO\OAuthConsentContext;
$code = app(OAuthServerService::class)->approveAuthorizationRequest(
$authorization,
$user,
new OAuthConsentContext(scopes: ['invoices.read'], remember: true),
);The client exchanges the code at:
text
POST /oauth/tokenAuthorization codes are one-time use and expire quickly.
Client Credentials
Create a client with client_credentials grant:
php
$secret = app(OAuthClientRepository::class)->createClient(new OAuthClientData(
name: 'M2M Client',
allowedGrants: ['client_credentials'],
allowedScopes: ['invoices.read'],
));The token endpoint accepts:
text
grant_type=client_credentials
client_id=...
client_secret=...
scope=invoices.readClient-credentials tokens authenticate as clients, not users.
Protect Resource Routes
php
Route::middleware(['sp.oauth', 'sp.oauth.scope:invoices.read'])
->get('/partner/invoices', Controller::class);Available middleware:
sp.oauthsp.oauth.scope:<scope>sp.oauth.any_scope:<scope1>,<scope2>sp.oauth.client:<client_id>
Revoke and Introspect
php
app(OAuthServerService::class)->revokeToken($token);
$payload = app(OAuthServerService::class)->introspect($token);