8.4 KiB
EasyStream API Authentication Guide
Overview
EasyStream now supports modern JWT token-based authentication for API clients, alongside traditional session-based authentication for web pages.
Authentication Systems
1. Session-Based Authentication (Traditional Web Pages)
- Uses PHP sessions with cookies
- Managed by
VAuth::login()andVAuth::logout() - Stored in
db_sessionstable - Best for: Traditional server-rendered pages
2. JWT Token Authentication (Modern APIs)
- Uses Bearer tokens in Authorization header
- Managed by
VAuth::loginWithToken()andVAuth::validateJWTToken() - Stateless (no server-side session storage)
- Best for: SPAs, mobile apps, API clients
Backend API Endpoints
Base URL
http://localhost:8083/api
Authentication Endpoints
1. Login with Token (New)
Get a JWT token for API authentication.
Endpoint: POST /auth.php?action=login_token
Request Body:
{
"identifier": "username or email",
"password": "your_password",
"expires_in": 86400 // Optional: token expiry in seconds (default: 24 hours)
}
Response (Success):
{
"success": true,
"message": "Login successful",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400,
"user": {
"user_id": 1,
"username": "john_doe",
"email": "john@example.com",
"role": "member"
}
}
Response (Error):
{
"success": false,
"message": "Invalid credentials"
}
2. Verify Token
Validate a JWT token and get user information.
Endpoint: GET /auth.php?action=verify_token or POST /auth.php?action=verify_token
Authorization Header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Alternative (POST body):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response (Success):
{
"success": true,
"valid": true,
"user": {
"user_id": 1,
"username": "john_doe",
"email": "john@example.com",
"role": "member"
}
}
3. Traditional Login (Session-based)
For web pages that need PHP session authentication.
Endpoint: POST /auth.php?action=login
Request Body:
{
"identifier": "username or email",
"password": "your_password",
"remember_me": false
}
Response:
{
"success": true,
"message": "Login successful",
"user": { ... }
}
Note: This sets a PHP session cookie, not a JWT token.
Frontend API Helper Usage
Include the API Helper
Add to your HTML:
<script src="/f_scripts/fe/js/api-helper.js"></script>
Initialize API Client
// API client is automatically initialized as window.api
const api = window.api; // or new EasyStreamAPI()
Authentication Examples
Login and Get Token
try {
const result = await api.login('john_doe', 'password123');
if (result.success) {
console.log('Logged in!', result.user);
console.log('Token:', result.token);
// Token is automatically stored in localStorage
}
} catch (error) {
console.error('Login failed:', error.message);
}
Check Authentication Status
if (api.isAuthenticated()) {
console.log('User is authenticated');
} else {
console.log('User is not authenticated');
}
Get Current User Info
try {
const userData = await api.getCurrentUser();
console.log('Current user:', userData.user);
} catch (error) {
console.error('Not authenticated:', error);
}
Logout
try {
await api.logout();
console.log('Logged out successfully');
} catch (error) {
console.error('Logout error:', error);
}
Making Authenticated API Requests
The API helper automatically includes the Bearer token in all requests.
GET Request
try {
const videos = await api.get('/videos.php', {
page: 1,
limit: 20,
sort: 'newest'
});
console.log('Videos:', videos);
} catch (error) {
console.error('Error:', error);
}
POST Request
try {
const newVideo = await api.post('/videos.php', {
title: 'My Awesome Video',
description: 'Check this out!',
privacy: 'public'
});
console.log('Video created:', newVideo);
} catch (error) {
console.error('Error:', error);
}
PUT Request
try {
const updated = await api.put('/videos.php?id=123', {
title: 'Updated Title'
});
console.log('Video updated:', updated);
} catch (error) {
console.error('Error:', error);
}
DELETE Request
try {
const result = await api.delete('/videos.php?id=123');
console.log('Video deleted:', result);
} catch (error) {
console.error('Error:', error);
}
Manual Fetch Example (Without Helper)
If you prefer to use fetch() directly:
// Login and get token
const loginResponse = await fetch('/api/auth.php?action=login_token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
identifier: 'john_doe',
password: 'password123'
})
});
const loginData = await loginResponse.json();
const token = loginData.token;
// Store token
localStorage.setItem('jwt_token', token);
// Make authenticated request
const response = await fetch('/api/videos.php', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
const videos = await response.json();
cURL Examples
Login with Token
curl -X POST http://localhost:8083/api/auth.php?action=login_token \
-H "Content-Type: application/json" \
-d '{
"identifier": "john_doe",
"password": "password123"
}'
Verify Token
curl -X GET http://localhost:8083/api/auth.php?action=verify_token \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"
Authenticated API Request
curl -X GET http://localhost:8083/api/videos.php?page=1&limit=10 \
-H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"
Token Management
Token Storage
- Frontend: Stored in
localStoragewith expiry time - Backend: JWT is stateless (no server-side storage)
Token Expiry
- Default: 24 hours (86400 seconds)
- Configurable via
JWT_EXPIRYin.env - Client automatically clears expired tokens
Token Security
- Secret: Stored in
JWT_SECRETenvironment variable - Algorithm: HS256 (HMAC-SHA256)
- Validation: Signature verified on every request
Migration Guide
For Existing AJAX Code
Before (jQuery with sessions):
$.post('/some_endpoint.php', { action: 'do_something' }, function(data) {
console.log(data);
});
After (Fetch with JWT):
api.post('/some_endpoint.php', { action: 'do_something' })
.then(data => console.log(data))
.catch(error => console.error(error));
Environment Configuration
Update your .env file:
# JWT Configuration
JWT_SECRET=9a652ee880c41bafb0a81d38d54b029d63903eeaafccaa8c12880a913931f63b
JWT_EXPIRY=86400
# CORS Configuration (for separate frontends)
CORS_ORIGIN=http://localhost:3000
Error Handling
Common Errors
401 Unauthorized
{
"success": false,
"message": "Invalid or expired token"
}
Solution: Re-login to get a new token.
403 Forbidden
{
"success": false,
"message": "Access denied"
}
Solution: User doesn't have permission for this resource.
429 Rate Limited
{
"success": false,
"message": "Too many requests"
}
Solution: Wait before retrying.
Best Practices
- Always use HTTPS in production - JWT tokens should be transmitted over secure connections
- Store tokens securely - Use localStorage for web, secure storage for mobile
- Handle token expiry - Implement token refresh or re-login flow
- Validate on every request - Backend validates tokens on all protected endpoints
- Clear tokens on logout - Remove tokens from storage when user logs out
- Use CORS properly - Configure
Access-Control-Allow-Originfor your frontend domain
Support
For issues or questions, check:
- EasyStream documentation:
/docs/ - API logs:
f_data/logs/ - Error handling:
VLoggerandVErrorHandlerclasses