UniAuth OAuth2 / OpenID Connect
Integrate "Sign in with UniAuth" into your application.
Quick Start
- Go to Account → Developer and register your app to get a
client_idandclient_secret - Redirect users to the authorization endpoint with PKCE
- Exchange the authorization code for tokens at the token endpoint
- Use the access token to fetch user info
Endpoints
| Endpoint | URL |
|---|---|
| Discovery | https://uniauth.id/.well-known/openid-configuration |
| Authorization | https://uniauth.id/api/oauth/authorize |
| Token | https://uniauth.id/api/oauth/token |
| UserInfo | https://uniauth.id/api/oauth/userinfo |
| Revocation | https://uniauth.id/api/oauth/revoke |
| JWKS | https://uniauth.id/.well-known/jwks.json |
Scopes
| Scope | Claims |
|---|---|
openid | sub |
profile | name, given_name, family_name, picture |
email | email, email_verified |
JavaScript Example
// 1. Generate PKCE verifier and challenge
const verifier = crypto.randomUUID() + crypto.randomUUID();
const challenge = btoa(String.fromCharCode(
...new Uint8Array(await crypto.subtle.digest('SHA-256',
new TextEncoder().encode(verifier)))
)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
// 2. Redirect to authorize
const params = new URLSearchParams({
response_type: 'code',
client_id: 'YOUR_CLIENT_ID',
redirect_uri: 'https://yourapp.com/callback',
scope: 'openid profile email',
state: crypto.randomUUID(),
code_challenge: challenge,
code_challenge_method: 'S256',
});
window.location.href = 'https://uniauth.id/api/oauth/authorize?' + params;
// 3. Exchange code for tokens (server-side)
const tokenRes = await fetch('https://uniauth.id/api/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code: CODE_FROM_CALLBACK,
redirect_uri: 'https://yourapp.com/callback',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
code_verifier: verifier,
}),
});
const tokens = await tokenRes.json();
// 4. Fetch user info
const userRes = await fetch('https://uniauth.id/api/oauth/userinfo', {
headers: { Authorization: 'Bearer ' + tokens.access_token },
});
const user = await userRes.json();PHP Example (with SDK)
Download UniAuth.php and drop it into your project. It handles PKCE, CSRF, and token exchange automatically.
// UniAuth.php — single-file SDK, no dependencies (just PHP 8+ with curl)
require_once 'UniAuth.php';
$ua = new UniAuth(
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
redirectUri: 'https://yoursite.com/callback.php'
);
// ── Login page ──────────────────────────────
// Redirect the user to UniAuth:
header('Location: ' . $ua->getLoginUrl());
// ── Callback page (callback.php) ────────────
// Exchange code for user info (one line):
$user = $ua->handleCallback($_GET['code']);
// $user = [
// 'sub' => 'uuid-of-user',
// 'email' => '[email protected]',
// 'email_verified' => true,
// 'name' => 'John Doe',
// 'given_name' => 'John',
// 'family_name' => 'Doe',
// 'picture' => 'https://uniauth.id/api/avatar/...',
// '_tokens' => ['access_token' => '...', 'refresh_token' => '...']
// ]
// Create your session, match/create user in DB, done.
$_SESSION['user'] = $user;Python Example
import hashlib, base64, secrets, requests
# 1. Generate PKCE
verifier = secrets.token_urlsafe(32)
challenge = base64.urlsafe_b64encode(
hashlib.sha256(verifier.encode()).digest()
).rstrip(b'=').decode()
# 2. Redirect user to:
# https://uniauth.id/api/oauth/authorize?response_type=code&client_id=...
# &redirect_uri=...&scope=openid+profile+email
# &state=RANDOM&code_challenge={challenge}&code_challenge_method=S256
# 3. In your callback, exchange the code:
tokens = requests.post('https://uniauth.id/api/oauth/token', data={
'grant_type': 'authorization_code',
'code': code_from_callback,
'redirect_uri': 'https://yourapp.com/callback',
'client_id': 'YOUR_CLIENT_ID',
'client_secret': 'YOUR_CLIENT_SECRET',
'code_verifier': verifier,
}).json()
# 4. Fetch user info:
user = requests.get('https://uniauth.id/api/oauth/userinfo',
headers={'Authorization': f'Bearer {tokens["access_token"]}'}
).json()