- PHP 100%
| .gitignore | ||
| readme.md | ||
| sso.php | ||
SSO Client
Minimal library for authenticating users via the Sharkk SSO server. Drop sso.php into your project and you're done.
1. Register Your App with SSO
Send a POST /admin/services/{name} request to the SSO server:
curl -s -X POST https://sso.sharkk.net/admin/services/myapp \
-H 'X-Admin-Key: <admin_key>' \
-H 'Content-Type: application/json' \
-d '{"origins": ["https://myapp.sharkk.net"]}'
The response contains your secret and api_key — save these securely:
{
"name": "myapp",
"secret": "64-char-hex",
"api_key": "48-char-hex",
"origins": ["https://myapp.sharkk.net"]
}
First-party apps (on the same domain as SSO) can be marked
"first_party": truein the SSO server config to skip the user consent prompt.
2. Installation
Copy sso.php to your project and require it:
require 'sso.php';
$sso = new SSO([
'sso_url' => 'https://sso.sharkk.net',
'service_name' => 'myapp',
'secret' => 'your-64-char-hex-secret',
'api_key' => 'your-48-char-hex-api-key',
'callback_url' => 'https://myapp.sharkk.net/_auth/callback',
]);
3. Protecting a Page
Add one line to any page that requires authentication:
$user = $sso->require();
// $user['id'], $user['username'], $user['email'], $user['email_verified']
echo "Hello, " . htmlspecialchars($user['username']);
If the user is not logged in, they are automatically redirected to SSO login and back.
4. Handling the Callback
Create a callback endpoint at the URL you specified in callback_url. This is where SSO redirects after a successful login:
// _auth/callback.php
require 'sso.php';
$sso = new SSO([/* config */]);
try {
$user = $sso->handleCallback();
// User is now logged in — redirect to your app's home page
header('Location: /');
} catch (RuntimeException $e) {
// Token invalid or expired
http_response_code(400);
echo 'Authentication failed: ' . htmlspecialchars($e->getMessage());
}
5. Logging Out
$sso->logout('/'); // redirects to SSO logout, then back to /
This clears the local PHP session and redirects to the SSO logout endpoint, which invalidates the SSO session cookie.
6. Per-User App Data
Store arbitrary key-value data on the user's SSO account, namespaced to your app. This data is stored server-side in the SSO server and is accessible across any of your services that share the same namespace.
Requires: app and SSO server must share a cookie domain (e.g. both on *.sharkk.net).
Write data
$user = $sso->require();
$sso->setData('theme', 'dark');
$sso->setData('preferences', ['notifications' => true, 'language' => 'en']);
Read data
$theme = $sso->getData('theme', 'light'); // 'light' is the default
$prefs = $sso->getData('preferences', []);
$all = $sso->getAllData(); // returns ['theme' => 'dark', 'preferences' => [...]]
7. Server-to-Server API
Use these when you need user info outside of a browser request (e.g. in a background job or webhook handler):
// Look up any user by their SSO ID
$user = $sso->fetchUser($userId); // null if not found
// Check if a user has been admin-invalidated (forced logout)
if (!$sso->validateUser($userId)) {
// User was revoked — deny access
}
8. Full Example
A minimal PHP app with login, home page, and logout:
index.php (home page)
<?php
require 'sso.php';
$sso = new SSO([/* config */]);
$user = $sso->require(); // redirects to SSO if not logged in
$theme = $sso->getData('theme', 'light');
?>
<!DOCTYPE html>
<html>
<body data-theme="<?= htmlspecialchars($theme) ?>">
<p>Hello, <?= htmlspecialchars($user['username']) ?></p>
<a href="/logout.php">Log out</a>
</body>
</html>
_auth/callback.php (SSO callback)
<?php
require '../sso.php';
$sso = new SSO([/* config */]);
try {
$sso->handleCallback();
header('Location: /');
} catch (RuntimeException $e) {
http_response_code(400);
echo htmlspecialchars($e->getMessage());
}
logout.php
<?php
require 'sso.php';
$sso = new SSO([/* config */]);
$sso->logout('https://myapp.sharkk.net/');
9. Config Reference
| Key | Required | Description |
|---|---|---|
sso_url |
Yes | Base URL of the SSO server (no trailing slash) |
service_name |
Yes | Service name registered with SSO |
secret |
Yes | 64-char hex HMAC secret (for verifying tokens) |
api_key |
Yes | 48-char hex API key (for service-to-server calls) |
callback_url |
Yes | Full URL of your _auth/callback endpoint |
namespace |
No | K-V data namespace (defaults to service_name) |
session_key |
No | PHP $_SESSION key to use (default: _sso) |
10. Security Notes
- Tokens are verified with HMAC-SHA256 and a constant-time comparison — safe against timing attacks.
- The 5-minute token TTL means intercepted redirect tokens expire quickly.
- PHP sessions are configured with
httponly,secure, andsamesite=Lax. setDatauses your service API key viaPUT /api/users/{id}/data— server-to-server, no browser session required.- For high-security actions, call
$sso->validateUser($user['id'])to confirm the account has not been admin-revoked since the user last logged in.