JWT Token Specification
Technical reference for RegardingWork Hub JWT token structure and generation
Overview
RegardingWork Hub uses JSON Web Tokens (JWT) for secure authentication across the ecosystem. This page documents the exact token structure, payload format, and generation process.
Access Tokens
- Purpose: API authentication
- Lifespan: 24 hours
- Contains: Full user data
Refresh Tokens
- Purpose: Token renewal
- Lifespan: 30 days
- Contains: Minimal user data
Token Generation
Algorithm & Security
- Algorithm: HS256 (HMAC with SHA-256)
- Secret Key:
JWT_SECRET_KEY
environment variable - Unique ID: UUID v4 for each token (JTI field)
Generation Code
// Location: auth_service.py - AuthService.generate_tokens()
@staticmethod
def generate_tokens(user):
now = datetime.utcnow()
# Access token payload
access_payload = {
'user_id': user.id,
'username': user.username,
'email': user.email,
'iat': now,
'exp': now + timedelta(seconds=current_app.config['JWT_ACCESS_TOKEN_EXPIRES']),
'jti': str(uuid.uuid4()),
'type': 'access'
}
access_token = jwt.encode(
access_payload,
current_app.config['JWT_SECRET_KEY'],
algorithm='HS256'
)
Access Token Payload
Most Common Token Type
This is the token format you'll encounter when integrating with Hub APIs and validating user authentication.
Example Payload
{
"user_id": 29,
"username": "michelini",
"email": "michelini@shadstone.com",
"iat": 1757300500,
"exp": 1757386900,
"jti": "da1a6a63-d0a7-4cdc-8bea-865de5a13f02",
"type": "access"
}
Field Descriptions
Field | Type | Description | Example |
---|---|---|---|
user_id |
Integer | Database user ID (primary key) | 29 |
username |
String | User's login username | "michelini" |
email |
String | User's email address | "michelini@shadstone.com" |
iat |
Integer | Unix timestamp when token was issued | 1757300500 |
exp |
Integer | Unix timestamp when token expires | 1757386900 |
jti |
String | Unique JWT ID (UUID v4 format) | "da1a6a63-d0a7-4cdc-8bea-865de5a13f02" |
type |
String | Token type identifier | "access" |
Refresh Token Payload
Refresh tokens contain minimal data and are used only for obtaining new access tokens.
Example Payload
{
"user_id": 29,
"iat": 1757300500,
"exp": 1759114551,
"jti": "07b92835-1f33-4058-b3e3-abc93d2ea031",
"type": "refresh"
}
Field Descriptions
Field | Type | Description | Example |
---|---|---|---|
user_id |
Integer | Database user ID | 29 |
iat |
Integer | Unix timestamp when issued | 1757300500 |
exp |
Integer | Unix timestamp when expires (30 days) | 1759114551 |
jti |
String | Unique JWT ID | "07b92835-1f33-4058-b3e3-abc93d2ea031" |
type |
String | Token type identifier | "refresh" |
Token Usage & Validation
API Authentication
Include access tokens in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Token Validation
Validate tokens using the /api/auth/validate
endpoint:
// Request
GET /api/auth/validate
Authorization: Bearer YOUR_ACCESS_TOKEN
// Response
{
"success": true,
"user": {
"id": 29,
"username": "michelini",
"email": "michelini@shadstone.com"
}
}
Token Expiration
- Access Tokens: 24 hours (86400 seconds)
- Refresh Tokens: 30 days (2592000 seconds)
- Renewal: Use
/api/auth/refresh
with refresh token
Debug Information
Token Structure
JWT tokens consist of three parts separated by dots:
header.payload.signature
// Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyOSwidXNlcm5hbWUiOiJtaWNoZWxpbmkiLCJlbWFpbCI6Im1pY2hlbGluaUBzaGFkc3RvbmUuY29tIiwiaWF0IjoxNzU3MzAwNTAwLCJleHAiOjE3NTczODY5MDAsImp0aSI6ImRhMWE2YTYzLWQwYTctNGNkYy04YmVhLTg2NWRlNWExM2YwMiIsInR5cGUiOiJhY2Nlc3MifQ.CyRkFNQW7Ihv_aXSQCiz_2U65-CErKzh_sroGnQ4OXo
Decoding Tokens
You can decode the payload (middle section) using base64 decoding:
// JavaScript example
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoyOSwidXNlcm5hbWUiOiJtaWNoZWxpbmkiLCJlbWFpbCI6Im1pY2hlbGluaUBzaGFkc3RvbmUuY29tIiwiaWF0IjoxNzU3MzAwNTAwLCJleHAiOjE3NTczODY5MDAsImp0aSI6ImRhMWE2YTYzLWQwYTctNGNkYy04YmVhLTg2NWRlNWExM2YwMiIsInR5cGUiOiJhY2Nlc3MifQ.CyRkFNQW7Ihv_aXSQCiz_2U65-CErKzh_sroGnQ4OXo";
const parts = token.split('.');
const payload = JSON.parse(atob(parts[1]));
console.log(payload); // Shows decoded token payload
Security Note
Never decode and trust JWT payloads without proper signature verification. Always validate tokens through Hub's API endpoints.
Common Issues
Invalid Token Format
Symptom: 401 Unauthorized errors
Cause: Missing "Bearer " prefix or malformed token
Fix: Ensure Authorization header format: Bearer TOKEN
Token Expired
Symptom: 401 errors after 24 hours
Cause: Access token exceeded lifespan
Fix: Use refresh token to get new access token