How to Set Up SSO Authentication for Quick Builder

Last updated: 2026-03-03

How to Set Up SSO Authentication for Quick Builder

Quick Builder authenticates users through JWT-based SSO. Your server generates a signed JWT containing the user's identity, then redirects them to the Xeni booking engine. This article covers how to create, sign, and deliver JWT tokens.

JWT Requirements

All JWT tokens for Quick Builder must meet these requirements:

RequirementValue
AlgorithmHS256 (HMAC with SHA-256)
Secret key length32 characters minimum
Maximum expiry30 minutes from issue time

Required JWT Claims

Every token must include the following claims in its payload:

ClaimTypeDescription
issstringIssuer identifier — your application's domain or name
iatnumberIssued-at time as a Unix timestamp (seconds since epoch)
expnumberExpiration time as a Unix timestamp (must be within 30 minutes of iat)
useridstringUnique identifier for the user in your system
emailstringUser's email address
firstnamestringUser's first name
last_namestringUser's last name

Example JWT Payload

JSON
{
  "iss": "partner-app.example.com",
  "iat": 1740000000,
  "exp": 1740001800,
  "userid": "usrabc123",
  "email": "jane.doe@example.com",
  "first_name": "Jane",
  "last_name": "Doe"
}

Generating a JWT Token

Node.js Example

JAVASCRIPT
const jwt = require('jsonwebtoken');

const SECRET_KEY = 'your-secret-key-at-least-32-chars!'; // 32+ characters

function generateQuickBuilderToken(user) {
const payload = {
iss: 'partner-app.example.com',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (30 * 60), // 30 minutes
user_id: user.id,
email: user.email,
first_name: user.firstName,
last_name: user.lastName
};

return jwt.sign(payload, SECRET_KEY, { algorithm: 'HS256' });
}

Python Example

PYTHON
import jwt
import time

SECRET_KEY = 'your-secret-key-at-least-32-chars!' # 32+ characters

def generatequickbuilder_token(user):
now = int(time.time())
payload = {
'iss': 'partner-app.example.com',
'iat': now,
'exp': now + (30 * 60), # 30 minutes
'user_id': user['id'],
'email': user['email'],
'firstname': user['firstname'],
'lastname': user['lastname']
}
return jwt.encode(payload, SECRET_KEY, algorithm='HS256')

Redirecting the User

Once you have a signed token, redirect the user to the Xeni SSO URL:

https://your-xeni-domain.com/sso?token={JWTTOKEN}&navigateTo={ENCODEDDESTINATION}

Example Redirect (Node.js)

JAVASCRIPT
app.get('/launch-booking', (req, res) => {
  const token = generateQuickBuilderToken(req.user);
  const destination = encodeURIComponent('/hotels/search');
  const ssoUrl = https://your-xeni-domain.com/sso?token=${token}&navigateTo=${destination};
  res.redirect(ssoUrl);
});

Security Best Practices

  • Never expose your secret key in client-side code. JWT signing must happen on your server.
  • Use a strong secret key with at least 32 characters. A randomly generated key is recommended.
  • Keep expiry short. The maximum allowed is 30 minutes, but shorter values (5-10 minutes) reduce the window of risk if a token is intercepted.
  • Generate a new token for each redirect. Do not reuse tokens across sessions.
  • Store the secret securely using environment variables or a secrets manager — never hardcode it in source files.

Troubleshooting

IssueCauseSolution
Token rejectedSecret key mismatchVerify the secret key matches what is configured in the Xeni admin panel
Token expiredexp claim is in the pastGenerate a fresh token immediately before redirecting
Invalid algorithmNot using HS256Ensure your JWT library is configured to use HS256
Missing claimsRequired claim omittedVerify all seven required claims are present in the payload

Next Steps

After you can generate valid JWT tokens, you need to build a validation endpoint that Xeni will call to verify those tokens.

Was this article helpful?