Spaces:
Runtime error
Iframe SSO Authentication System - API Documentation
Overview
This system enables secure SSO authentication for Iframe embeds from third-party websites. It validates source domains against a whitelist and generates reusable API keys for seamless user authentication.
Architecture
Frontend (Edlink Payload)
β
Check Login Status (/auth/iframe/status)
β
ββ IF Logged In β Render Iframe
β
ββ IF NOT Logged In:
ββ Request API Key (/auth/api-key/generate)
ββ Whitelist Validation
ββ Verify API Key (/auth/api-key/verify)
ββ Get JWT Token
ββ Set Secure Cookie
ββ Render Iframe
Endpoints
1. Check Login Status
Endpoint: GET /v1/auth/iframe/status
Description: Check if user is already logged in via JWT token
Headers:
Authorization: Bearer <jwt_token>
Response (200):
{
"is_logged_in": true,
"user_token": "user-uuid-token",
"email": "user@example.com",
"name": "John Doe"
}
Errors:
401 Unauthorized- No valid token or inactive user
2. Generate API Key
Endpoint: POST /v1/auth/api-key/generate
Description: Generate API key with whitelist validation
Request Body:
{
"email": "user@example.com",
"username": "johndoe",
"phone": "+62812345678",
"name": "John Doe",
"identity_number": "1234567890123456",
"source_domain": "https://abdanhafidz.github.io/edlink-simulation"
}
Response (200):
{
"api_key": "generated-api-key-here",
"message": "API key generated successfully"
}
Errors:
401 Unauthorized- Source domain not whitelisted400 Bad Request- Invalid payload data
3. Verify API Key & Login
Endpoint: POST /v1/auth/api-key/verify
Query Parameters:
api_key(string, required) - The API key from step 2
Response (200):
{
"message": "Login successful",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": "2024-05-20 22:50:00"
}
Cookies Set:
access_token(HttpOnly, Secure, SameSite=Lax)
Errors:
401 Unauthorized- Invalid API key
Whitelist Management (Admin)
Add Domain to Whitelist
Endpoint: POST /v1/auth/whitelist
Request Body:
{
"source_type": "domain",
"value": "https://abdanhafidz.github.io/edlink-simulation",
"description": "Edlink Simulation Platform",
"is_active": true
}
Supported Formats:
- Exact domain:
example.com,https://example.com - Wildcard subdomain:
*.example.com,https://*.example.com - Full URL:
https://abdanhafidz.github.io/edlink-simulation
Security Features
Whitelist Validation
- All source domains must be whitelisted before API key generation
- Supports exact matching, wildcard subdomains, and full URLs
- Case-insensitive domain matching
API Key Security
- API keys are hashed before storage (SHA-256)
- Plain API key only returned once during generation
- Reusable keys for convenient third-party integration
- Can be revoked at any time
JWT Token Security
- Tokens stored in secure HTTP-only cookies
- Auto-expire after 1 hour
- Validated on every protected request
- Secure flag set for HTTPS-only transmission
User Creation
- Auto-created users for new third-party users
- Unique user_token per user
- Email uniqueness enforced
- Default secure password (not shared with frontend)
Implementation Flow (Frontend Example)
// Step 1: Check if already logged in
async function checkLoginStatus() {
const response = await fetch('/v1/auth/iframe/status', {
headers: {
'Authorization': `Bearer ${getCookie('access_token')}`
}
});
if (response.ok) {
renderIframe(); // Already logged in
return;
}
// Not logged in, proceed to Step 2
generateAndVerifyAPIKey();
}
// Step 2: Generate API Key
async function generateAndVerifyAPIKey() {
const apiKeyResponse = await fetch('/v1/auth/api-key/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: userData.email,
username: userData.username,
phone: userData.phone,
name: userData.name,
identity_number: userData.identityNumber,
source_domain: window.location.origin
})
});
const apiKeyData = await apiKeyResponse.json();
const apiKey = apiKeyData.api_key;
// Step 3: Verify API Key & Get JWT
await fetch(`/v1/auth/api-key/verify?api_key=${apiKey}`, {
method: 'POST'
});
// JWT token is now in secure cookie
renderIframe();
}
// Helper: Get cookie value
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
Database Schema
Whitelist Table
CREATE TABLE whitelist (
id INT PRIMARY KEY AUTO_INCREMENT,
created_at DATETIME,
updated_at DATETIME,
source_type VARCHAR(50),
value VARCHAR(255) UNIQUE INDEX,
description VARCHAR(255),
is_active BOOLEAN DEFAULT TRUE
);
API Key Table
CREATE TABLE api_key (
id INT PRIMARY KEY AUTO_INCREMENT,
created_at DATETIME,
updated_at DATETIME,
user_token VARCHAR(255) INDEX,
api_key_hash VARCHAR(255) UNIQUE,
source_domain VARCHAR(255) INDEX,
is_active BOOLEAN DEFAULT TRUE
);
Environment Requirements
No additional environment variables needed beyond existing FastAPI setup.
Testing
Run migration:
alembic upgrade head
Run tests:
pytest tests/