Service Integration Guide
Complete implementation guide for integrating your RegardingWork service with Hub authentication
Configured Services: ✅ All Ready for Integration
All RegardingWork services have CORS and SSO domain permissions configured and ready to use
Services Active:
Game • Premium • Display • CE • Family • Desk
Game • Premium • Display • CE • Family • Desk
🔧 Configured RegardingWork Services
The following services are pre-configured and ready for Hub authentication integration:
- game.regardingwork.com - Game Platform
- premium.regardingwork.com - Premium Music Service
- display.regardingwork.com - Display Service
- ce.regardingwork.com - CE Application
- family.regardingwork.com - Family Service
- desk.regardingwork.com - Desk Service
Need a new service added? Contact the Hub team to add your domain to the CORS and SSO configuration.
📋 Complete Implementation Example
Real-world integration guide using Family Service
1. Create Authentication Service
Create a centralized authentication service for your app:
class RegardingWorkAuth {
constructor() {
this.hubBaseUrl = 'https://hub.regardingwork.com/api';
this.currentUser = null;
}
async initialize() {
// Check for existing session on app start
const user = await this.validateSession();
if (user) {
this.currentUser = user;
return true;
}
return false;
}
async login(username, password) {
try {
const response = await fetch(`${this.hubBaseUrl}/auth/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: username,
password: password
})
});
if (response.ok) {
const data = await response.json();
// Store tokens securely
localStorage.setItem('access_token', data.access_token);
localStorage.setItem('refresh_token', data.refresh_token);
this.currentUser = data.user;
return {
success: true,
user: data.user,
tokens: {
access: data.access_token,
refresh: data.refresh_token
}
};
} else {
const error = await response.json();
throw new Error(error.error || 'Authentication failed');
}
} catch (error) {
console.error('Hub authentication failed:', error);
return {
success: false,
error: error.message
};
}
}
async validateSession() {
const token = localStorage.getItem('access_token');
if (!token) return false;
try {
const response = await fetch(`${this.hubBaseUrl}/auth/validate`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
const data = await response.json();
return data.user; // User is authenticated
} else {
// Token invalid or expired - try refresh
return await this.refreshToken();
}
} catch (error) {
console.error('Token validation failed:', error);
return false;
}
}
async refreshToken() {
const refreshToken = localStorage.getItem('refresh_token');
if (!refreshToken) return false;
try {
const response = await fetch(`${this.hubBaseUrl}/auth/refresh`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
refresh_token: refreshToken
})
});
if (response.ok) {
const data = await response.json();
// Update stored token
localStorage.setItem('access_token', data.access_token);
return data.user;
} else {
// Refresh failed - user needs to login again
this.clearTokens();
return false;
}
} catch (error) {
console.error('Token refresh failed:', error);
return false;
}
}
async logout() {
const token = localStorage.getItem('access_token');
const refreshToken = localStorage.getItem('refresh_token');
try {
// Revoke tokens on server
await fetch(`${this.hubBaseUrl}/auth/logout`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
refresh_token: refreshToken
})
});
} catch (error) {
console.warn('Server logout failed, clearing local tokens anyway');
}
this.clearTokens();
this.currentUser = null;
}
clearTokens() {
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
}
isAuthenticated() {
return this.currentUser !== null;
}
getUser() {
return this.currentUser;
}
getAuthHeaders() {
const token = localStorage.getItem('access_token');
return token ? { 'Authorization': `Bearer ${token}` } : {};
}
}
2. Implementation Usage
How to use the authentication service in your app:
// Initialize authentication on app start
const auth = new RegardingWorkAuth();
// Check for existing session
auth.initialize().then(loggedIn => {
if (loggedIn) {
console.log('User already authenticated:', auth.getUser());
showDashboard();
} else {
showLoginForm();
}
});
// Handle login form submission
async function handleLogin(username, password) {
const result = await auth.login(username, password);
if (result.success) {
console.log('Login successful:', result.user);
showDashboard();
} else {
console.error('Login failed:', result.error);
showError(result.error);
}
}
// Handle logout
async function handleLogout() {
await auth.logout();
showLoginForm();
}
// Making authenticated API calls to your service
async function makeAuthenticatedRequest(url, options = {}) {
const authHeaders = auth.getAuthHeaders();
const response = await fetch(url, {
...options,
headers: {
...options.headers,
...authHeaders
}
});
if (response.status === 401) {
// Token might be expired, try refreshing
const refreshed = await auth.refreshToken();
if (refreshed) {
// Retry with new token
return makeAuthenticatedRequest(url, options);
} else {
// Refresh failed, redirect to login
auth.clearTokens();
showLoginForm();
return null;
}
}
return response;
}
3. Login Form HTML
Simple login form for your service:
<!-- Login Form -->
<div id="loginForm" class="login-container">
<div class="card">
<div class="card-header">
<h3>Login to RegardingWork Family</h3>
</div>
<div class="card-body">
<form id="authForm">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" required>
</div>
<button type="submit" class="btn btn-primary w-100">
Login with RegardingWork Hub
</button>
</form>
<div id="errorMessage" class="alert alert-danger mt-3 d-none"></div>
</div>
</div>
</div>
<!-- Dashboard (shown after login) -->
<div id="dashboard" class="d-none">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<span class="navbar-brand">RegardingWork Family</span>
<div class="navbar-nav ms-auto">
<span id="userInfo" class="navbar-text me-3"></span>
<button class="btn btn-outline-light" onclick="handleLogout()">Logout</button>
</div>
</div>
</nav>
<div class="container mt-4">
<h1>Welcome to RegardingWork Family!</h1>
<p>You are now authenticated with RegardingWork Hub.</p>
</div>
</div>
<script>
// Form handling
document.getElementById('authForm').addEventListener('submit', async function(e) {
e.preventDefault();
const username = document.getElementById('username').value;
const password = document.getElementById('password').value;
const errorDiv = document.getElementById('errorMessage');
errorDiv.classList.add('d-none');
const result = await auth.login(username, password);
if (result.success) {
showDashboard();
} else {
errorDiv.textContent = result.error;
errorDiv.classList.remove('d-none');
}
});
function showLoginForm() {
document.getElementById('loginForm').classList.remove('d-none');
document.getElementById('dashboard').classList.add('d-none');
}
function showDashboard() {
document.getElementById('loginForm').classList.add('d-none');
document.getElementById('dashboard').classList.remove('d-none');
const user = auth.getUser();
document.getElementById('userInfo').textContent = `Hello, ${user.username}!`;
}
function showError(message) {
const errorDiv = document.getElementById('errorMessage');
errorDiv.textContent = message;
errorDiv.classList.remove('d-none');
}
</script>
Security Best Practices
✅ Do:
- Store tokens in secure storage (localStorage for web, keychain for native)
- Implement automatic token refresh before expiration
- Clear tokens completely on logout
- Handle 401 responses with token refresh attempts
- Use HTTPS for all API calls
- Validate user sessions on app startup
❌ Don't:
- Log tokens to console or error messages
- Store tokens in unsecured locations
- Ignore token expiration handling
- Make requests without error handling
- Store passwords or sensitive data
- Skip server-side token revocation on logout
📊 Expected API Responses
Successful Login Response:
{
"message": "Login successful",
"user": {
"id": 19,
"username": "familyuser",
"email": "user@family.com",
"role": "USER",
"premium_tier": "FREE",
"is_active": true,
"created_at": "2025-08-21T14:53:11.449505",
"email_verified": true
},
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
Authentication Error Response:
{
"error": "Invalid credentials"
}
Token Validation Response:
{
"valid": true,
"user": {
"id": 19,
"username": "familyuser",
"role": "USER"
}
}
Testing Your Integration
Test Credentials:
Username:
Password:
janechen
Password:
jane123
Integration Checklist:
- Login form submits to Hub API correctly
- Tokens are stored securely after login
- User info displays correctly after authentication
- Token validation works on page refresh
- Automatic token refresh handles expired tokens
- Logout clears tokens and redirects to login
- Error handling shows user-friendly messages
- CORS requests work without errors
Common Issues & Solutions
Problem: Browser blocks requests with CORS errors.
Solution: Your domain should already be configured. If you get CORS errors, contact the Hub team to add your domain.
Check: Ensure you're using the exact domain name (e.g.,
Solution: Your domain should already be configured. If you get CORS errors, contact the Hub team to add your domain.
Check: Ensure you're using the exact domain name (e.g.,
https://family.regardingwork.com
)
Problem: API returns 401 when making authenticated requests.
Solutions:
Solutions:
- Check token is included in Authorization header:
Bearer {token}
- Try refreshing the token if it's expired
- Clear tokens and re-authenticate if refresh fails
- Verify credentials are correct
Problem: Requests fail with "Failed to fetch" or similar.
Solutions:
Solutions:
- Check Hub service status at hub.regardingwork.com
- Implement retry logic with exponential backoff
- Check browser network tab for detailed error information
- Verify you're using HTTPS URLs
Need Help?
If you encounter issues not covered in this guide:
- Check the full troubleshooting guide
- Review the API documentation
- Test with the provided credentials:
janechen / jane123
- Contact the RegardingWork Hub team for domain configuration issues