hytale-community / hytale-auth-php
A framework-agnostic PHP library for Sign in with Hytale using OpenID Connect and PKCE.
Package info
github.com/Hytale-Community/hytale-auth-php
pkg:composer/hytale-community/hytale-auth-php
Requires
- php: ^8.2
- firebase/php-jwt: ^7.1
- psr/http-client: ^1.0
- psr/http-factory: ^1.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.95
- guzzlehttp/guzzle: ^8.2
- phpunit/phpunit: ^11.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-09-14 22:48:01 UTC
README
Framework-agnostic PHP library for Sign in with Hytale using OpenID Connect, Authorization Code flow and PKCE.
The package provides the core authentication flow without depending on Laravel, Symfony or another framework. It uses PSR HTTP interfaces so the HTTP implementation remains up to the consuming application.
Package:
hytale-community/hytale-auth-php
Features
- OpenID Connect Authorization Code flow
- PKCE with
S256 - Public and confidential OAuth clients
stateandnoncegeneration and validation- Hytale OpenID discovery
- RS256 ID token validation using Hytale JWKS
- Validation of
iss,aud,expandnonce - Typed ID token claims
- UserInfo support
- Refresh token rotation support
- Token revocation
- Framework-agnostic PSR-18 / PSR-17 architecture
Requirements
- PHP 8.2+
- A PSR-18 HTTP client implementation
- PSR-17 request and stream factories
- A Hytale third-party application
Installation
composer require hytale-community/hytale-auth-php
The core package depends on PSR interfaces only. Your application must provide compatible HTTP implementations.
For example, with Guzzle:
composer require guzzlehttp/guzzle
Hytale endpoints
By default, the library uses the official Hytale OpenID Connect issuer:
https://connect.accounts.hytale.com
The library retrieves and validates Hytale's provider metadata through:
https://connect.accounts.hytale.com/.well-known/openid-configuration
UserInfo and JWKS URLs are read from that metadata. Authorization, token and revocation requests use Hytale's standard issuer paths documented above.
Configuration
use HytaleCommunity\HytaleAuth\Configuration; $configuration = new Configuration( clientId: 'your-client-id', redirectUri: 'https://example.com/auth/hytale/callback', );
For a confidential client, provide the client secret:
$configuration = new Configuration( clientId: 'your-client-id', redirectUri: 'https://example.com/auth/hytale/callback', clientSecret: 'your-client-secret', );
Confidential clients authenticate against the token endpoint using HTTP Basic authentication. The client secret is never sent in the form body.
Creating the client
The package accepts PSR-compatible HTTP dependencies.
Using Guzzle:
use GuzzleHttp\Client; use GuzzleHttp\Psr7\HttpFactory; use HytaleCommunity\HytaleAuth\HytaleClient; $httpClient = new Client(); $httpFactory = new HttpFactory(); $hytale = new HytaleClient( configuration: $configuration, httpClient: $httpClient, requestFactory: $httpFactory, streamFactory: $httpFactory, );
Starting an authentication flow
use HytaleCommunity\HytaleAuth\Scope; $authorization = $hytale->createAuthorizationRequest([ Scope::Profile, Scope::GameOwnership, ]);
openid is automatically included when it is missing.
Before redirecting the user, persist these values in your session or another temporary server-side store:
$authorization->state; $authorization->nonce; $authorization->codeVerifier;
Then redirect the user to:
$authorization->url;
Available scopes
| Enum | Hytale scope |
|---|---|
Scope::OpenId |
openid |
Scope::Profile |
hytale:profile |
Scope::SharedSource |
account:shared_source |
Scope::GameOwnership |
account:game_ownership |
Scope::ParentalManaged |
account:parental_managed |
Scope::Offline |
offline |
Use Scope::Offline when your Hytale application is allowed to receive refresh tokens.
Handling the callback
Pass the callback query parameters and the values stored before the redirect:
$result = $hytale->authenticate( parameters: $_GET, expectedState: $_SESSION['hytale_state'], codeVerifier: $_SESSION['hytale_code_verifier'], expectedNonce: $_SESSION['hytale_nonce'], );
The library will:
- Handle OAuth errors returned by Hytale.
- Validate the callback
state. - Exchange the authorization code using PKCE.
- Discover Hytale's OpenID configuration.
- Retrieve Hytale's JWKS.
- Validate the ID token signature and claims.
- Return the validated tokens and claims.
Authentication result
Validated identity claims are available through:
$result->claims->subject; $result->claims->profileUuid; $result->claims->profileUsername; $result->claims->sharedSource; $result->claims->gameOwnership; $result->claims->parentalManaged;
Tokens are available through:
$result->tokens->accessToken; $result->tokens->idToken; $result->tokens->expiresIn; $result->tokens->refreshToken; $result->tokens->tokenType;
Subject vs profile UUID
The OIDC sub claim is the stable user identifier for your Hytale application:
$result->claims->subject;
It should normally be used as the primary external account identifier in your application. The value is application-specific, so the same Hytale account can have a different sub in another third-party application.
A Hytale profile UUID is a separate public profile identity:
$result->claims->profileUuid;
When hytale:profile is requested, the user selects a Hytale profile during authentication. The profile UUID represents that selected public profile rather than the application-specific account identifier.
UserInfo
You can retrieve the current claims associated with an access token:
$userInfo = $hytale->userInfo( $result->tokens->accessToken, );
Then access:
$userInfo->subject; $userInfo->profileUuid; $userInfo->profileUsername; $userInfo->sharedSource; $userInfo->gameOwnership; $userInfo->parentalManaged;
Refresh tokens
If refresh tokens are enabled for your Hytale application and the offline scope was requested:
$newTokens = $hytale->refresh($storedRefreshToken);
Hytale refresh tokens rotate. When a refresh succeeds, replace the stored refresh token with the new one returned by Hytale:
$storedRefreshToken = $newTokens->refreshToken;
Do not reuse the old refresh token after a successful refresh. Reusing an old rotated token may invalidate the refresh token chain.
Revoking a token
Revoke a token when disconnecting a Hytale account or invalidating an authenticated session:
$hytale->revoke($refreshToken);
Error handling
OAuth errors returned by Hytale are exposed through OAuthException:
use HytaleCommunity\HytaleAuth\Exception\OAuthException; try { $result = $hytale->authenticate( parameters: $_GET, expectedState: $state, codeVerifier: $codeVerifier, expectedNonce: $nonce, ); } catch (OAuthException $exception) { $exception->error; $exception->errorDescription; }
Hytale may return OAuth errors such as:
access_denied
invalid_scope
invalid_request
invalid_grant
invalid_client
unauthorized_client
Validation failures such as an invalid state, nonce, issuer, audience or malformed response are rejected by the library.
Malformed or incomplete JSON responses from Hytale are exposed through UnexpectedResponseException:
use HytaleCommunity\HytaleAuth\Exception\UnexpectedResponseException;
Security notes
Always store state, nonce and the PKCE code_verifier server-side between the authorization redirect and callback.
Never expose a confidential client secret to browser or frontend code.
Redirect URIs registered with Hytale must match exactly. localhost and 127.0.0.1 are different redirect URIs.
Access tokens are opaque. Do not parse them. Use the validated ID token claims or the UserInfo endpoint instead.
ID tokens are validated against Hytale's RS256 JWKS and checked for the expected issuer, audience, expiration and nonce.
Authorization codes are short-lived and single-use. Exchange them immediately and never attempt to reuse them.
Local development
A local redirect URI can use HTTP when using localhost or 127.0.0.1, provided that exact URI is registered in your Hytale application.
Example:
http://localhost:8000/auth/hytale/callback
When developing this package alongside another Composer project, you can use a path repository:
{
"repositories": [
{
"type": "path",
"url": "../hytale-auth-php",
"options": {
"symlink": true
}
}
]
}
Then require the local development version:
composer require hytale-community/hytale-auth-php:@dev
Testing
Install development dependencies and run:
composer install
composer lint
composer test
Apply the configured PHP CS Fixer rules with:
composer format
The test suite mocks Hytale's HTTP endpoints and covers PKCE, authorization callbacks, token exchange, refresh-token rotation, revocation, malformed responses, ID token validation, UserInfo and public/confidential client behavior without contacting the real Hytale authentication service.
Framework integrations
This package intentionally contains no framework-specific session, cache, routing or persistence code.
A dedicated Laravel integration can build on top of this package while keeping the PHP SDK framework-agnostic.
License
MIT