Overview
MinistryHub implements JWT (JSON Web Token) authentication using HMAC-SHA256 signing. Tokens are generated upon successful login and must be included in API requests to access protected resources.Token Structure
JWT tokens consist of three base64url-encoded parts separated by dots:Header
- typ: Token type (JWT)
- alg: Signing algorithm (HMAC-SHA256)
Payload
The JWT payload contains user identification and timing information:User’s member ID from the database
User’s email address
Issued At timestamp (Unix timestamp)
Expiration timestamp (Unix timestamp, iat + 3600 seconds)
Signature
The signature is generated by:- Concatenating the base64url-encoded header and payload with a dot
- Signing with HMAC-SHA256 using the server’s secret key
- Base64url-encoding the resulting hash
Token Generation
Tokens are generated during:- Standard Login (
POST /api/auth/login) - Google OAuth Callback (
/api/auth/google/callback) - Invitation Acceptance (
POST /api/auth/accept-invite)
Generation Process
Token Validation
TheAuthMiddleware validates tokens on every protected API request:
Validation Steps
- Extract Token: From
Authorization: Bearer <token>header or query parameter - Verify Signature: Recalculate signature and compare with token signature
- Check Expiration: Ensure current time is before the
exptimestamp - Return User ID: Extract
uidfrom payload for request context
Token Extraction Methods
Tokens are accepted from multiple sources (in order of priority):AuthorizationheaderHTTP_AUTHORIZATIONserver variableREDIRECT_HTTP_AUTHORIZATION(for some server configurations)tokenquery parameter (for SSE/EventSource)
Token Expiration
- Lifetime: 3600 seconds (1 hour)
- Behavior: Expired tokens return
401 Unauthorized - Refresh: Re-authenticate via
/api/auth/loginto obtain a new token
Checking Token Expiration
Security Implementation
Secret Key
The JWT secret is stored in the server configuration:Base64URL Encoding
MinistryHub uses URL-safe base64 encoding:- Replace
+with- - Replace
/with_ - Remove padding
=
Error Handling
Invalid Token
- Signature verification fails
- Token is expired
- Token format is invalid
Missing Token
- No
Authorizationheader is present - No
tokenquery parameter is found - Header format is incorrect (not
Bearer <token>)
Implementation Examples
JavaScript/Fetch
PHP/cURL
Python/Requests
Best Practices
Secure Storage
Store tokens in secure, HTTP-only cookies or encrypted local storage
HTTPS Only
Always transmit tokens over HTTPS to prevent interception
Token Refresh
Implement token refresh logic before expiration
Logout Handling
Clear tokens from client storage on logout
Related Resources
Authentication Guide
Learn how to authenticate and obtain JWT tokens