Overview
CryptoPulse uses JWT (JSON Web Token) bearer authentication to secure all price endpoints. Clients must authenticate via the login endpoint, receive an access token, and include it in theAuthorization header for subsequent requests.
The
/docs Swagger UI and /docs-json OpenAPI spec are publicly accessible without authentication.Authentication Flow
Step 1: Login
Request
POST credentials to the login endpoint:Response
Login Implementation
The login logic insrc/auth/auth.service.ts validates credentials against environment variables:
src/auth/auth.service.ts
The current implementation uses a single admin account configured via environment variables. For production use, consider integrating a user database.
Environment Configuration
.env
- JWT_SECRET
- JWT_EXPIRES_IN
Required. Secret key for signing tokens.
- Must be at least 32 characters
- Use a cryptographically random string
- Never commit to version control
Rate Limiting on Login
Login endpoint is rate-limited to prevent brute-force attacks:src/auth/auth.controller.ts
429 Too Many Requests.
Step 2: Using the Token
Include the token in theAuthorization header with the Bearer scheme:
Token Validation
All protected endpoints use theJwtAuthGuard:
src/price/price.controller.ts
JwtAuthGuard Implementation
The guard extracts and verifies the token:src/auth/guards/jwt-auth.guard.ts
Validation Steps
Parse Bearer token
Validates format:
Bearer <token>Common errors:- Missing header →
401 Missing Authorization header - Wrong format (e.g., just the token without “Bearer”) →
401 Authorization header must use Bearer token - Token contains spaces →
401 Invalid Bearer token
Check expiration
Ensures token hasn’t exceeded
JWT_EXPIRES_INIf expired → 401 Invalid or expired tokenJWT Module Configuration
The JWT module is configured insrc/auth/auth.module.ts:
src/auth/auth.module.ts
parseJwtExpirationSeconds converts formats like 1h to seconds:
Error Responses
Login Errors
- 400 Bad Request
- 429 Too Many Requests
Protected Endpoint Errors
- 401 Missing header
- 401 Wrong format
- 401 Invalid token
Authorization header provided.Swagger Integration
The Swagger UI at/docs is configured for bearer auth:
src/main.ts
Using Swagger UI
Authorize
Click the Authorize button (top right), paste token in format:Or just paste the token directly - Swagger adds “Bearer” automatically.
Security Best Practices
Secure token storage
Secure token storage
Client-side:
- Use
httpOnlycookies for web apps (prevents XSS) - Use secure storage APIs for mobile apps
- Never store in localStorage if XSS risk exists
- Never log full tokens
- Use environment variables for secrets
- Rotate
JWT_SECRETperiodically
Token expiration
Token expiration
- Short-lived tokens (1h) reduce risk if compromised
- Implement refresh tokens for long-running clients
- Force re-authentication for sensitive operations
Rate limiting
Rate limiting
- Login endpoint is rate-limited by default
- Consider IP-based limits for additional protection
- Monitor for brute-force patterns
HTTPS in production
HTTPS in production
- ALWAYS use HTTPS in production
- Tokens in plain HTTP can be intercepted
- Configure HSTS headers
Common Issues
Token expired
Token expired
Symptom:
401 Invalid or expired token after some time.Solution: Re-authenticate via POST /auth/login to get a fresh token.Wrong header format
Wrong header format
Symptom:
401 Authorization header must use Bearer token.Solution: Ensure header is Authorization: Bearer <token>, not just the token.Secret mismatch
Secret mismatch
Symptom: Token from one instance doesn’t work on another.Solution: Ensure all instances use the SAME
JWT_SECRET.Clock skew
Clock skew
Symptom: Token appears expired immediately or works when it shouldn’t.Solution: Synchronize system clocks (NTP) across all instances.
Testing Authentication
Manual Test
Unit Test Example
From the codebase:Next Steps
API Reference
View detailed login endpoint documentation
Rate Limiting
Learn about throttling and rate limits