API Communication Security
Overview
StockEase Frontend communicates with the backend API using HTTPS with JWT-based authentication. This directory documents security practices, threat mitigation strategies, and best practices for API communication.
Security Architecture
Browser"] ApiClient["Axios ApiClient
With Interceptors"] AuthService["Auth Service
JWT Handling"] Interceptor["Request Interceptor
Token Attachment"] Response["Response Interceptor
Error Handling"] Backend["Backend API
HTTPS Endpoint"] Token["JWT Token
localStorage"] Client -->|HTTP Requests| ApiClient Client -->|Login/Logout| AuthService AuthService -->|Store/Retrieve| Token ApiClient -->|Attach Bearer Token| Interceptor Interceptor -->|POST/GET/PUT/DELETE| Backend Backend -->|200/4xx/5xx| Response Response -->|Handle 401| Token Response -->|Error Logging| Client style Client fill:#e3f2fd style ApiClient fill:#fff3e0 style AuthService fill:#e8f5e9 style Backend fill:#f3e5f5 style Token fill:#fce4ec
Key Components
1.
Axios API Client
(src/services/apiClient.ts)
- Configured HTTP client with automatic token attachment
- Request/response logging for debugging
- 401 error handling (unauthorized token cleanup)
- 2-minute request timeout
- Bearer token automatic injection
See: API Security & Configuration
2. JWT
Authentication (src/api/auth.ts)
- User login with username/password
- JWT token extraction from response
- Role-based access control (RBAC)
- Client-side payload decoding
- Token lifecycle management
See: Authentication & Token Handling
3. Error Handling & Logging
- API error logging and tracking
- 401 unauthorized response handling
- Network error differentiation
- Sensitive data protection in logs
- Error propagation to ErrorBoundary
See: Error Logging & Monitoring
4. Environment Configuration
VITE_API_BASE_URLfor backend endpoint- Build-time environment variable injection
- Development proxy for local testing
- Production HTTPS enforcement
Security Principles
β Implemented
- Bearer Token Authentication β JWT tokens sent via Authorization header
- Automatic Token Attachment β Request interceptor adds token to all requests
- 401 Error Handling β Clears token on unauthorized responses
- Request Logging β API calls logged for debugging
- Timeout Protection β 2-minute timeout prevents hanging requests
- Environment Isolation β API endpoint configured per environment
β οΈ Considerations
localStorage Storage β Tokens in localStorage are accessible to XSS attacks
- Recommendation: Use HttpOnly cookies for better security
- Current: localStorage fallback for development flexibility
Client-Side Payload Decoding β JWT payload decoded in browser
- Expected: Backend must verify signature (payload is unsigned)
- Safe: Payload contains no secrets (only claims like role, user ID)
Console Logging β Request/response details logged to console
- Risk: Sensitive headers may appear in logs
- Mitigation: Filter sensitive data before logging in production
CORS Configuration β Handled by backend, not frontend
- Frontend Role: Sends correct headers via Axios
- Backend Role: Validates origin, allows safe CORS headers
API Endpoints
Authentication
POST /api/auth/login
Content-Type: application/json
Body: { username: string, password: string }
Response: { success: boolean, data: string (JWT token) }
Products (All require Authorization header)
GET /api/products β Fetch all products
GET /api/products/paged β Fetch paginated products
POST /api/products β Create product
DELETE /api/products/:id β Delete product
GET /api/products/:id β Get product by ID
GET /api/products/search β Search products by name
PUT /api/products/:id/quantity β Update quantity
PUT /api/products/:id/price β Update price
Headers:
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
Request/Response Flow
1. Successful Request with Token
Client Request
β
Request Interceptor
ββ Retrieve token from localStorage
ββ Attach: Authorization: Bearer <token>
ββ Log request details
ββ Send to backend
β
Backend Validation
ββ Verify JWT signature
ββ Check token expiration
ββ Extract user claims (role, username)
ββ Process request
β
Response Interceptor
ββ Log response status/data
ββ Return data to caller
ββ Store in component state
2. Unauthorized Response (401)
Backend Response: 401 Unauthorized
β
Response Interceptor
ββ Detect error.response?.status === 401
ββ Remove token from localStorage
ββ Log warning: "Unauthorized access - redirecting to login"
ββ Throw error to caller
ββ Component handles redirect to login
3. Network Error
Network Failure (timeout, no connection)
β
Response Interceptor
ββ Catch error
ββ Log error details
ββ Throw to caller
ββ Component shows "Unexpected error" message
Environment Variables
Development
VITE_API_BASE_URL=http://localhost:8081- Used for local development with backend running locally
- Vite proxy forwards
/api/*requests to backend
Production
VITE_API_BASE_URL=https://api.stockease.com- Set at build time via GitHub Actions secrets
- All requests use HTTPS
- CORS validated by backend
Configuration
// vite.config.ts
server: {
proxy: {
'/api': {
target: env.VITE_API_BASE_URL || 'http://localhost:8081',
changeOrigin: true, // β
Ensures Host header matches target
secure: false, // β
Allows self-signed certs in dev
},
},
},Common Scenarios & Solutions
β Token Expired During Request
Scenario: User's token expires while making an API call
Current Behavior:
- Request sent with valid token
- Backend returns 401 (token expired)
- Response interceptor removes token
- Component re-renders, showing login screen
Improvement Opportunity:
- Implement token refresh mechanism with refresh tokens
- Automatically retry failed request after refresh
- Reduce user friction during long sessions
β CORS Errors in Browser
Scenario: Request from
https://frontend.com to
https://api.stockease.com fails
Cause: Browser blocks cross-origin requests without proper CORS headers
Frontend Role:
- Send request with correct headers β
- Cannot override CORS policy (browser enforces)
Backend Responsibility:
- Add
Access-Control-Allow-Originheader - Add
Access-Control-Allow-Credentialsif cookies used - Add
Access-Control-Allow-Methodsfor HTTP verbs - Add
Access-Control-Allow-Headersfor custom headers
Test:
curl -i -H "Origin: https://frontend.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Authorization" \
https://api.stockease.com/api/productsβ Sensitive Data in Logs
Scenario: Authorization header or response data logged to console
Risk: Token or user data exposed in browser dev tools
Current Code:
console.log('API Request:', config); // β οΈ Includes full headers
console.log('API Response:', response); // β οΈ Includes sensitive dataRecommended Improvement:
// Filter sensitive headers before logging
const safeConfig = {
...config,
headers: {
...config.headers,
Authorization: '[REDACTED]', // Hide token
Cookie: '[REDACTED]',
},
};
console.log('API Request:', safeConfig);
// In production, remove logging entirely
if (process.env.NODE_ENV === 'development') {
console.log('API Response:', response);
}Related Documentation
- API Security & Configuration β Detailed axios setup, interceptors, and security settings
- Error Logging & Monitoring β Error handling, logging strategies, and troubleshooting
- Authentication & Authorization β JWT, token storage, role-based access
- Frontend Security Checklist β Pre-deployment security checks
- Incident Response Playbook β Response procedures for security issues
Quick Reference
| Concern | Solution | Status |
|---|---|---|
| Token attached to requests | Request interceptor with Bearer token | β Implemented |
| 401 handling | Remove token, redirect to login | β Implemented |
| Request timeout | 2-minute timeout configured | β Implemented |
| CORS support | Backend handles, frontend sends correct headers | β Implemented |
| Error logging | Console logging (filter sensitive data) | β οΈ Needs improvement |
| Token refresh | Not implemented | β³ Future enhancement |
| HttpOnly cookies | Not implemented (using localStorage) | β οΈ Recommendation |
| Secure production API | HTTPS required | β Enforced |
Last Updated: November 13, 2025
Author: StockEase Security Team
Review Cycle: Quarterly