A powerful extension for the XAuth plugin that provides an OAuth 2.0-like authentication layer, allowing external web applications to securely access player data.
- OAuth 2.0 Flow: Implements a standard authorization code flow for secure authentication.
- Web Server Integration: Runs a built-in, configurable web server to handle API requests.
- Registered Clients: Securely manage which external applications can connect, with unique client IDs and secrets.
- Rate Limiting: Protects your server from abuse with configurable request limits per client.
- Extensible Scopes: Allows other plugins to register their own data scopes, making player data available via the API.
- Database Support: Supports SQLite and MySQL for storing authorization codes and tokens.
- XAuth: This plugin is an extension of XAuth and requires it to be installed and active.
- PMMP WebServer: The web server functionality is provided by this library, which is bundled with the plugin.
- Download the latest stable version of XAuthConnect from Poggit CI.
- Place the
XAuthConnect.pharfile into theplugins/folder of your PocketMine-MP server. - Restart your server. The plugin will generate its configuration files.
The plugin generates a config.yml file in plugin_data/XAuthConnect/ upon first run.
enabled: (true/false) Master switch to enable or disable the web server.server-port: The port the web server will listen on (e.g., 8443).base-url: The public base URL of your server (e.g., "https://mc.yourdomain.com").code-timeout: How long (in seconds) an authorization code is valid.
cert-folder: The folder withinplugin_data/XAuthConnect/containing your SSL certificate files (.pem,.cert).passphrase: The passphrase for your private key, if it is encrypted.
This is where you define the applications that can connect to your server.
registered-clients:
forum:
client-id: "forum_client_123"
client-secret: "super_secret_key"
name: "Community Forum"
redirect-uris:
- "https://forum.example.com/auth/callback"
allowed-scopes:
- "profile:nickname"
- "profile:uuid"
rate-limits:
requests-per-minute: 60client-id: A unique identifier for your application.client-secret: A secret key known only to your application and the server.name: A display name for the application, shown on the login page.redirect-uris: A list of valid URLs where the user can be redirected after authorization.allowed-scopes: The data scopes this client is allowed to request.rate-limits: The maximum number of requests per minute this client can make.
type: The database type to use (sqliteormysql).worker-limit: Number of threads for database queries.sqlite: Contains thefilename for the SQLite database.mysql: Contains connection details (host,user,password,database,port) for MySQL.
XAuthConnect provides a set of HTTP endpoints to handle the authentication flow.
Starts the authorization process. This endpoint renders an HTML login page for the user.
- Query Parameters:
client_id(required): The ID of the registered client.redirect_uri(required): The callback URL where the user will be sent after login.scope(required): A space-separated list of requested data scopes (e.g.,profile:nickname profile:uuid).code_challenge(required): A PKCE code challenge.code_challenge_method(required): The method used to derive the code challenge (S256 or plain).state(optional): An opaque value used to maintain state between the request and callback.
Handles the form submission from the authorize page.
- Form Parameters:
client_id,redirect_uri,scope,state(from the authorize step).code_challenge(required): The code challenge from the authorize step.code_challenge_method(required): The code challenge method (S256 or plain).username(required): The player's username.password(required): The player's XAuth password.
- On Success: Redirects the user to the
/xauth/consentpage to confirm scope access.
Displays a consent page to the user, asking them to approve or deny the requested scopes.
- Query Parameters:
client_id(required): The ID of the registered client.redirect_uri(required): The callback URL where the user will be sent after authorization.scope(required): A space-separated list of requested data scopes.state(optional): An opaque value used to maintain state between the request and callback.code_challenge(required): The code challenge from the authorize step.code_challenge_method(required): The code challenge method (S256 or plain).username(required): The username of the authenticated player.
- On Approval (POST):
- Form Parameters: Same as query parameters, plus
consent_action(value:approve). - On Success: Redirects the user to the
redirect_uriwith a temporarycodeand the originalstate.
- Form Parameters: Same as query parameters, plus
- On Denial (POST):
- Form Parameters: Same as query parameters, plus
consent_action(value:deny). - On Success: Redirects the user to the
redirect_uriwith anaccess_deniederror.
- Form Parameters: Same as query parameters, plus
Exchanges an authorization code for an access token. This should be a server-to-server request.
- Form Parameters:
client_id(required): The client ID.client_secret(required): The client secret.code(required): The authorization code received from the login step.code_verifier(required): The PKCE code verifier.
- On Success: Returns a JSON object with the access token.
{ "access_token": "your_long_lived_access_token", "token_type": "Bearer", "expires_in": 3600 }
Exchanges a refresh token for a new access token (and optionally a new refresh token).
- Form Parameters:
client_id(required): The client ID.client_secret(required): The client secret.refresh_token(required): The refresh token obtained previously.
- On Success: Returns a JSON object with the new access token and refresh token.
{ "access_token": "new_long_lived_access_token", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "new_refresh_token" }
Allows a client to query the active state of an access or refresh token.
- Form Parameters:
token(required): The access token or refresh token to introspect.token_type_hint(optional): Hint about the type of the token (access_tokenorrefresh_token).client_id(required): The client ID.client_secret(required): The client secret.
- On Success: Returns a JSON object indicating the token's active status and associated metadata.
If the token is inactive or invalid:
{ "active": true, "scope": "profile:nickname profile:uuid", "client_id": "forum_client_123", "username": "Steve", "exp": 1678886400 }{ "active": false }
Allows a client to revoke an access token or refresh token.
- Form Parameters:
token(required): The access token or refresh token to revoke.token_type_hint(optional): Hint about the type of the token (access_tokenorrefresh_token).client_id(required): The client ID.client_secret(required): The client secret.
- On Success: Returns an empty 200 OK response.
Fetches user data using a valid access token.
- Headers:
Authorization: Bearer <access_token>
- On Success: Returns a JSON object containing the user data for the scopes granted to the token.
{ "profile:nickname": "Steve", "profile:uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
XAuthConnect allows other plugins to provide custom data scopes.
-
Create a ScopeProvider: Your class must implement the
ChernegaSergiy\XAuthConnect\api\ScopeProviderinterface.// In your plugin: src/MyPlugin/EconomyScopeProvider.php namespace MyPlugin; use ChernegaSergiy\XAuthConnect\api\ScopeProvider; class EconomyScopeProvider implements ScopeProvider { public function getProvidedScopes(): array { return ["economy:balance", "economy:level"]; } public function retrieveScopeData(string $username, array $scopes): array { $data = []; // Your logic to get player data, e.g., from EconomyAPI $balance = 123.45; // placeholder $level = 5; // placeholder foreach ($scopes as $scope) { if ($scope === 'economy:balance') { $data['economy:balance'] = $balance; } if ($scope === 'economy:level') { $data['economy:level'] = $level; } } return $data; } }
-
Register your provider: In your plugin's
onEnable(), get theXAuthConnectinstance and register your provider.// In your plugin: src/MyPlugin/Main.php $xauthConnect = $this->getServer()->getPluginManager()->getPlugin("XAuthConnect"); if ($xauthConnect instanceof \ChernegaSergiy\XAuthConnect\Main) { $xauthConnect->registerScopeProvider(new EconomyScopeProvider()); $this->getLogger()->info("Registered custom economy scopes with XAuthConnect."); }
-
Update Client Configuration: Server administrators can now add your new scopes (
economy:balance,economy:level) to theallowed-scopeslist for any client inconfig.yml.
The HTML for the authorization login page (login.html) is copied from the plugin's internal resources to plugin_data/XAuthConnect/web/login.html on first run. You can customize the login page by editing this file in the plugin_data folder.
Customizing Static Assets (CSS, JS, Images):
The plugin's web server does serve static files from the plugin_data/XAuthConnect/web/static/ directory.
To include custom CSS, JavaScript, or images:
- Manually create a
static/subfolder insideplugin_data/XAuthConnect/web/. - Place your custom files (e.g.,
styles.css) inside thisstatic/folder. - Link to them in your
login.htmlusing the/xauth/assets/URL path.
For example, if you have plugin_data/XAuthConnect/web/static/styles.css, you can link to it in login.html like this:
<link rel="stylesheet" href="/xauth/assets/styles.css">The template uses several placeholders that are replaced by the plugin:
{{client_name}}: Displays thenameof the application the user is logging into.{{error_message}}: Shows an error message if a previous login attempt failed. This is an HTML block, often a Bootstrap alert.{{oauth_params}}: This is a crucial placeholder that injects hidden input fields (client_id,redirect_uri,scope,state) into the form, ensuring the OAuth 2.0 parameters are passed along correctly. This must be included inside your<form>tag.
Contributions are welcome and appreciated! Here's how you can contribute:
- Fork the project on GitHub.
- Create your feature branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add some AmazingFeature'). - Push to the branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
Please make sure to update tests as appropriate and adhere to the existing coding style.
This project is licensed under the CSSM Unlimited License v2 (CSSM-ULv2). Please note that this is a custom license. See the LICENSE file for details.