PHP Installation
Client OAuth — PHP Installation (XWMS)
Description: Secure, advanced login and authentication APIs for businesses (XWMS). This page focuses on installing and using the XwmsApiHelperPHP
library in PHP. It's written so even a 10‑year‑old can follow the main ideas, but it also includes full, step‑by‑step technical instructions for developers.
Quick Install ( Fast track )
Follow these three steps to get going quickly.
- Install with Composer
composer require xwms/package guzzlehttp/guzzle vlucas/phpdotenv
- Create a
.env
file (recommended)
Create a file called .env
in your project root:
XWMS_CLIENT_ID=your_client_id_here
XWMS_DOMAIN=your_domain_here # like example.com
XWMS_CLIENT_SECRET=your_secret_here
XWMS_CLIENT_DOMAIN=your-domain.example
XWMS_REDIRECT_URI=http://localhost/xwms/validateToken
XWMS_API_URL=https://api.xwms.example/
- Use the helper and visit the authenticate route
Use the XwmsApiHelperPHP
class to redirect users to XWMS and validate tokens on return. See the full examples below.
Full, Friendly, Step-by-Step Installation (Explained)
Imagine XWMS is a friendly gatekeeper for your website. When someone wants to get into your site, they go to XWMS, XWMS checks who they are, and then lets them back in with a special ticket (a token).
We will:
- Install the software that talks to the gatekeeper.
- Tell our app the secret keys that XWMS gives us (we keep them hidden in a
.env
file). - Make two doors (URLs): one to send the user to XWMS, and another to accept them when XWMS sends them back with the ticket.
.env
? Why use
Think of .env
like a locked treasure chest in your project where you hide secret keys. We use vlucas/phpdotenv
to open that chest when the app starts.
Install dotenv:
composer require vlucas/phpdotenv
Then add this at the start of your app (for example public/index.php
or bootstrap.php
):
require __DIR__ . '/vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->safeLoad(); // loads .env if present, but won't crash if missing
Now you can read your secrets with getenv('XWMS_CLIENT_ID')
or $_ENV['XWMS_CLIENT_ID']
.
Project Layout Recommendation
A small, safe layout for a plain PHP app:
/project-root
/public
index.php
/src
XwmsApiHelperPHP.php
/config
xwms.php
.env
composer.json
Put xwms.php
in config/
with default fallback values that read from environment variables.
Example config/xwms.php
:
<?php
return [
'client_id' => getenv('XWMS_CLIENT_ID') ?: null,
'client_secret' => getenv('XWMS_CLIENT_SECRET') ?: null,
'client_domain' => getenv('XWMS_CLIENT_DOMAIN') ?: null,
'client_redirect' => getenv('XWMS_REDIRECT_URI') ?: 'http://localhost/xwms/validateToken',
'xwms_api_url' => rtrim(getenv('XWMS_API_URL') ?: 'https://api.xwms.example/', '/') . '/',
];
XwmsApiHelperPHP
Class — How it Works (Short) The
This helper does three main things:
- Builds requests with your client id/secret.
- Asks XWMS for a redirect URL (
sign-token
) and redirects the user there. - After the user returns, it verifies the token with
sign-token-verify
.
The class uses Guzzle to make HTTP calls and expects JSON responses.
XwmsApiHelperPHP
(Recommended) Example A — Using
This example shows a minimal plain PHP flow. Place the helper in /src/XwmsApiHelperPHP.php
(your class as provided).
public/index.php (very small example)
<?php
require __DIR__ . '/../vendor/autoload.php';
// load env
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->safeLoad();
use XWMS\Package\Controllers\Api\XwmsApiHelperPHP;
$path = $_SERVER['REQUEST_URI'];
if ($path === '/xwms/auth') {
// redirect user to XWMS
$helper = new XwmsApiHelperPHP();
$helper->auth(); // this will send a Location header and exit
}
if ($path === '/xwms/validateToken') {
try {
$helper = new XwmsApiHelperPHP();
$result = $helper->authValidate(); // will POST token to verify
// Example result handling
if (!empty($result['status']) && $result['status'] === 'success') {
// safely extract user fields
$user = $result['data'] ?? [];
echo "Welcome, " . htmlspecialchars($user['name'] ?? 'User') . "!";
} else {
echo "Authentication failed: " . htmlspecialchars(json_encode($result));
}
} catch (Exception $e) {
http_response_code(400);
echo "Error: " . htmlspecialchars($e->getMessage());
}
}
// otherwise show a simple link
if ($path === '/') {
echo '<a href="/xwms/auth">Login with XWMS</a>';
}
Notes:
auth()
calls the API, gets a redirect URI, and issuesheader('Location: ...')
.authValidate()
reads$_GET['token']
and callssign-token-verify
.
Example B — Not using the helper (Manual Guzzle flow)
If you want more control or don't want to use the helper class, here is how to perform the same flow manually.
<?php
require __DIR__ . '/../vendor/autoload.php';
use GuzzleHttp\Client;
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->safeLoad();
$clientId = getenv('XWMS_CLIENT_ID');
$clientSecret = getenv('XWMS_CLIENT_SECRET');
$clientDomain = getenv('XWMS_CLIENT_DOMAIN');
$apiBase = rtrim(getenv('XWMS_API_URL'), '/') . '/';
$guzzle = new Client(['base_uri' => $apiBase, 'timeout' => 10]);
// 1) Ask for a sign-token (get redirect url)
try {
$resp = $guzzle->post('sign-token', [
'headers' => [
'X-Client-Id' => $clientId,
'X-Client-Secret' => $clientSecret,
'X-Client-Domain' => $clientDomain,
'Accept' => 'application/json',
],
'json' => [
'redirect_url' => getenv('XWMS_REDIRECT_URI')
]
]);
$body = json_decode((string) $resp->getBody(), true);
$redirectUrl = $body['data']['url'] ?? $body['redirect_url'] ?? null;
if ($redirectUrl) {
header('Location: ' . $redirectUrl);
exit;
}
} catch (\Throwable $e) {
echo 'Error contacting XWMS: ' . htmlspecialchars($e->getMessage());
exit;
}
// 2) When user returns to /xwms/validateToken?token=abc -> verify:
// Example verification request
try {
$token = $_GET['token'] ?? null;
$resp = $guzzle->post('sign-token-verify', [
'headers' => [
'X-Client-Id' => $clientId,
'X-Client-Secret' => $clientSecret,
'X-Client-Domain' => $clientDomain,
'Accept' => 'application/json',
],
'json' => [
'token' => $token
]
]);
$data = json_decode((string) $resp->getBody(), true);
// handle $data similar to helper example
} catch (\Throwable $e) {
echo 'Verification failed: ' . htmlspecialchars($e->getMessage());
}
This manual approach does the exact same steps as the helper but gives you the freedom to change headers, timeouts, or logging.
Security Best Practices (Very Important)
- Never commit
.env
to git. Add.env
to.gitignore
. - Limit secret access. Only your server and deployment system should have the
.env
file. - Use HTTPS for your
XWMS_REDIRECT_URI
and your app in production. - Validate inputs. Never trust
$_GET
or$_POST
without checking and sanitizing. - Use short token lifetimes and treat returned tokens as sensitive. Store them encrypted if you must store.
- Log safely. Do not log client secrets, tokens, or sensitive user info. Log only useful debugging info.
Troubleshooting Tips (Practical)
- If login doesn't redirect: check
.env
values and theXWMS_API_URL
andXWMS_REDIRECT_URI
. - If token verification fails: inspect the HTTP response body in logs (
storage/logs
or your error log) for error messages. - If you see
Missing required client configuration.
— that meansclient_id
,client_secret
, orclient_domain
were not found by the code. Check yourconfig/xwms.php
and.env
values.
Example Responses (What the API might return)
A successful verify may look like:
{
"status": "success",
"message": "Successful authenticated",
"data": {
"email": "jane@example.com",
"name": "Jane Doe",
"email_verified": true
}
}
An error may look like:
{
"status": "error",
"message": "Invalid token",
"data": {}
}
Always check status
and do not assume data
exists.
Useful Extra Tips
- Use environment-specific
.env
files (for example.env.local
,.env.production
) and a secure deployment pipeline. - If you deploy on a platform (Heroku, DigitalOcean, Vercel), use the platform's secret management to store these keys.
- For local development you can use
php -S localhost:8000 -t public
to quickly test.
Summary (One-liner)
Install via Composer, keep secrets in .env
with vlucas/phpdotenv
, use XwmsApiHelperPHP
to manage the redirect & verification flow (or do it manually with Guzzle), and always follow security best practices.
End of document.