Status
Implemented and verified locally. Real IdP round-trip verification (JWKS fetch, token sign/verify against a live XID instance) has not been performed yet and must be completed before production use.
Registry status: UNPUBLISHED. Install this SDK only from the repository source checkout; do not use an external package registry.
Request authentication is Bearer-only by default. An application-owned JWT cookie is read only when its exact name is configured. The opaque __Host-xid.rt.* Core cookie is never scanned or verified locally; exchange it by forwarding the complete Cookie header to exact same-origin POST /v1/sessions/token with redirects disabled, and accept only a response containing the token field.
Install
PHP 8.1+ required. Core dependencies are pulled automatically by Composer.
{
"repositories": [
{ "type": "path", "url": "../xid/sdk/php" }
],
"require": {
"xid/xid": "dev-main"
}
}
# composer update xid/xidQuick start
use Xid\XidClient;
use Xid\Exception\TokenException;
use Xid\Exception\JwksException;
$xid = new XidClient([
'issuer' => 'https://xid.dev',
'audience' => 'your-client-id',
'cache' => $psrSimpleCacheImpl, // PSR-16; null disables JWKS cache
]);
try {
$claims = $xid->verifyToken($jwtString);
echo $claims->sub(); // user ID
echo $claims->scope(); // "openid profile email"
echo implode(',', $claims->amr()); // "phr" / "otp"
} catch (TokenException $e) {
http_response_code(401);
} catch (JwksException $e) {
http_response_code(503);
}Authenticate a PSR-7 request
$result = $xid->authenticateRequest($psrRequest);
if ($result->isAuthenticated()) {
$userId = $result->claims()->sub();
} else {
// $result->reason() for server-side logs only
http_response_code(401);
}
$token = $xid->exchangeSessionToken(
'https://app.example.com/account',
$psrRequest->getHeaderLine('Cookie'),
$sessionTokenTransport,
);Verify webhook
use Xid\Exception\WebhookException;
try {
$payload = $xid->verifyWebhook($psrRequest, 'whsec_...');
$type = $payload->type(); // "user.created"
$data = $payload->data();
} catch (WebhookException $e) {
http_response_code(400);
}XidClient options
| Key | Default | Description |
|---|---|---|
issuer |
required | XID issuer URI |
audience |
null |
Expected audience; null skips validation |
cache |
null |
PSR-16 CacheInterface for JWKS caching |
jwks_ttl |
3600 |
JWKS cache TTL in seconds |
clock_leeway |
0 |
JWT clock skew tolerance in seconds |
cookie_name |
disabled |
Application-owned JWT cookie name; disabled unless explicitly configured |
XidClient methods
| Method | Returns | Description |
|---|---|---|
verifyToken(string $token) |
Claims |
Verify JWT string; throws on failure |
authenticateRequest(ServerRequestInterface $request) |
AuthResult |
Authenticate PSR-7 request; does not throw |
verifyWebhook(ServerRequestInterface $request, string $secret) |
WebhookPayload |
Validate webhook signature; throws on failure |
refreshJwks() |
void |
Force-refresh the JWKS cache |
Platform notes
- Uses
firebase/php-jwtfor ES256/RS256 verification. HS256 andnonealg are rejected. - Requires a PSR-7 request object for
authenticateRequestandverifyWebhook. Convert framework-native requests with a PSR-7 bridge if needed. - Exception hierarchy:
XidException->TokenException,JwksException,WebhookException.