Standardized solution for common SSO integration issues
Problem: SSO button redirects to Hub but doesn't return to mini-app with authentication.
Root Cause: Using wrong Hub endpoint for SSO.
// BROKEN - Don't use this
const ssoUrl = `https://hub.regardingwork.com/login?redirect_uri=https://your-app.com/login`;
/login is for web login, not SSO// CORRECT - Use this instead
function startSSO() {
const redirectUri = encodeURIComponent('https://your-app.com/api/auth/callback');
const ssoUrl = `https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=${redirectUri}&service=your-app`;
window.location.href = ssoUrl;
}
Update your SSO button to use the correct endpoint:
// Replace your current SSO function with this
function startSSO() {
const redirectUri = encodeURIComponent('https://your-app.com/api/auth/callback');
const ssoUrl = `https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=${redirectUri}&service=your-app-name`;
window.location.href = ssoUrl;
}
your-app.com and your-app-name with your actual values.
Create endpoint: /api/auth/callback to handle the token from Hub:
// Example for Node.js/Express
app.get('/api/auth/callback', (req, res) => {
const token = req.query.token;
if (!token) {
return res.redirect('/login?error=no_token');
}
// Store token securely
res.cookie('auth_token', token, {
httpOnly: true,
secure: true,
sameSite: 'strict'
});
// Redirect to dashboard/logged-in state
res.redirect('/dashboard');
});
CRITICAL: Validate the token and get user data correctly:
// Validate token with Hub API
async function validateToken(token) {
try {
const response = await fetch('https://hub.regardingwork.com/api/auth/validate', {
method: 'GET', // Must be GET method
headers: {
'Authorization': `Bearer ${token}`, // Must include "Bearer " prefix
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
// ⚠️ CRITICAL: User data is nested under 'user' key
const user = data.user; // ← This is the key!
console.log('User authenticated:', user.username, user.id);
// Now you can access user data:
// user.username, user.id, user.email, etc.
return { success: true, user: user };
} else {
throw new Error('Token validation failed');
}
} catch (error) {
console.error('SSO validation error:', error);
return { success: false, error: error.message };
}
}
Response structure: User data is nested under the user key.
✅ Correct: response.user.username
❌ Wrong: response.username (undefined - causes "invalid user data" error)
Make sure your SSO button calls the correct function:
<!-- Update your SSO button -->
<button onclick="startSSO()" class="btn btn-primary btn-lg w-100 mb-3">
<i class="fa fa-shield"></i> Sign in with RegardingWork Hub
</button>
response.user.username (not response.username)| Parameter | Required | Description | Example |
|---|---|---|---|
redirect_uri |
Yes | Your callback endpoint URL | https://your-app.com/api/auth/callback |
service |
Recommended | Your app name for identification | alivefor, your-app |
https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=https://your-app.com/api/auth/callback&service=your-app
| Error Message | Cause | Solution |
|---|---|---|
SSO authentication failed - invalid user data |
Using response.username instead of response.user.username |
Change to response.user.username in token validation code |
SSO authentication failed - no token received |
Callback endpoint not receiving token parameter | Check redirect_uri URL encoding and endpoint exists |
SSO authentication failed - token validation failed |
Wrong validation endpoint/method or missing Bearer prefix | Use GET method with Authorization: Bearer {token} |
"Invalid token: Not enough segments" |
JWT token is corrupted/truncated during redirect - has <3 segments | Check token length and URL encoding in callback endpoint |
400 Error: "Invalid redirect_uri domain" |
Domain not in Hub's SSO allowlist | Contact Hub admin to add domain via admin panel |
| SSO goes to Hub dashboard, doesn't return | Using wrong endpoint or redirect_uri | Use /api/auth/sso/authorize not /login |
Cannot read property 'access_token' of undefined |
Looking for token field instead of access_token |
Use response.access_token not response.token |
https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=...&service=...
https://hub.regardingwork.com/login?redirect_uri=...
// Test in browser console or Postman
const response = await fetch('https://hub.regardingwork.com/api/auth/validate', {
headers: { 'Authorization': `Bearer ${token}` }
});
console.log('Status:', response.status);
console.log('Data:', await response.json());
{"valid": true, "user": {...}}response.user.username not response.username
/api/auth/callback/api/auth/sso/authorize not /loginresponse.username but Hub returns response.user.usernameuser key
// ❌ WRONG - causes "invalid user data" error
const username = response.username; // undefined!
// ✅ CORRECT - this works
const username = response.user.username;
const userId = response.user.id;
response.username to response.user.username in your token validation code.
// Add to your callback endpoint to debug
console.log('Raw URL:', req.url);
console.log('Token received:', req.query.token);
console.log('Token length:', req.query.token?.length);
console.log('Token segments:', req.query.token?.split('.').length);
// Valid JWT should have exactly 3 segments
End-to-end SSO implementation based on the successful AliveFor integration
<!-- SSO Button -->
<a href="https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=https://yourapp.com/api/auth/callback&service=yourapp"
class="btn btn-primary btn-lg">
<i class="fa fa-shield"></i> Sign in with RegardingWork Hub
</a>
<!-- Or with JavaScript function -->
<button onclick="startSSO()" class="btn btn-primary btn-lg">
Sign in with RegardingWork Hub
</button>
<script>
function startSSO() {
const redirectUri = encodeURIComponent('https://yourapp.com/api/auth/callback');
const ssoUrl = `https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=${redirectUri}&service=yourapp`;
window.location.href = ssoUrl;
}
</script>
// SSO Callback Endpoint
app.get('/api/auth/callback', async (req, res) => {
const token = req.query.token;
if (!token) {
console.log('No token received');
return res.redirect('/login?error=no_token');
}
try {
// Validate token with Hub
const response = await fetch('https://hub.regardingwork.com/api/auth/validate', {
method: 'GET', // Must be GET
headers: {
'Authorization': `Bearer ${token}`, // Must include Bearer
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
// 🚨 CRITICAL: Use data.user.username not data.username
const username = data.user.username;
const userId = data.user.id;
// Store in session/database
req.session.username = username;
req.session.userId = userId;
req.session.token = token;
console.log('SSO login successful:', username);
res.redirect('/dashboard');
} else {
console.log('Token validation failed:', response.status);
res.redirect('/login?error=validation_failed');
}
} catch (error) {
console.log('SSO validation error:', error);
res.redirect('/login?error=service_unavailable');
}
});
// Reusable token validation function
async function validateTokenWithHub(token) {
try {
const response = await fetch('https://hub.regardingwork.com/api/auth/validate', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
return {
success: true,
user: data.user // ← User data is here
};
} else {
const error = await response.json();
return {
success: false,
error: error.error || 'Token validation failed'
};
}
} catch (error) {
return {
success: false,
error: 'Network error: ' + error.message
};
}
}
// Usage in middleware
function requireAuth(req, res, next) {
const token = req.session.token;
if (!token) {
return res.redirect('/login');
}
validateTokenWithHub(token).then(result => {
if (result.success) {
req.user = result.user; // Available in route
next();
} else {
res.redirect('/login');
}
});
}
This exact implementation successfully integrated AliveFor with RegardingWork Hub SSO after fixing the response.user.username parsing issue.
https://hub.regardingwork.com/login?redirect_uri=https://alivefor.com/login
https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=https://alivefor.com/api/auth/callback&service=alivefor
// Replace these values with your app's details
const APP_DOMAIN = 'your-app.com';
const APP_SERVICE_NAME = 'your-app';
function startSSO() {
const redirectUri = encodeURIComponent(`https://${APP_DOMAIN}/api/auth/callback`);
const ssoUrl = `https://hub.regardingwork.com/api/auth/sso/authorize?redirect_uri=${redirectUri}&service=${APP_SERVICE_NAME}`;
window.location.href = ssoUrl;
}
If SSO still doesn't work after following this guide: