API & Security Documentation
Comprehensive guide to the API security architecture, including JWT Authentication, Rate Limiting, and Attribute-Based Access Control.
Table of Contents
- JWT Authentication
- Rate Limiting
- Attribute-Based Security
- CSRF Protection
- Security Headers
- Infrastructure & Services
1. JWT Authentication
The system uses JSON Web Tokens (JWT) for stateless API authentication. The implementation supports HS256 algorithm.
Configuration
Set the secret key in your .env file:
JWT_SECRET=your_super_secret_key_hereLogin Endpoint
To obtain a token, send a POST request with credentials:
POST /api/auth/login
Content-Type: application/json
{
"email": "admin@example.com",
"password": "password"
}Returns a JSON object containing the token and token metadata.
Using the Token
Include the token in the Authorization header for protected requests:
Authorization: Bearer <your_token_here>Token Lifecycle
| Event | Behavior |
|---|---|
| Token Expiry | Default 1 hour; configurable via JWT_EXPIRY |
| Invalid Token | Returns 401 Unauthorized with error message |
| Missing Token | Falls back to session auth if available |
2. Rate Limiting (Throttling)
The API is protected by a Token Bucket algorithm-based rate limiter (Throttler). Limits can be defined per-controller or per-method.
Usage Attribute
Use the #[RateLimit] attribute to enforce limits:
use App\Attributes\RateLimit;
#[RateLimit(60, 60)] // 60 requests per 60 seconds (1 minute)
class UserController extends Controller {
// ...
}Parameters
| Parameter | Description | Example |
|---|---|---|
limit | Max number of requests allowed | 60 |
time | Time window in seconds | 60 |
Rate Limit Response
When rate limit is exceeded, the API returns:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
{
"error": "Rate limit exceeded",
"retry_after": 30
}3. Attribute-Based Security Guard
Security is enforced declaratively using PHP Attributes, similar to NestJS Guards. These are processed by the global SecurityAttributeFilter.
Available Attributes
| Attribute | Purpose | Location |
|---|---|---|
#[ApiAuth] | Enforces authentication (Session or Bearer Token) | App\Attributes\ApiAuth |
#[RateLimit] | Request throttling | App\Attributes\RateLimit |
Example Controller
use App\Attributes\ApiAuth;
use App\Attributes\RateLimit;
#[ApiAuth] // Protect entire controller
#[RateLimit(60, 60)] // Global limit for this controller
class UserController extends Controller
{
#[RateLimit(5, 60)] // Stricter limit for specific action
public function delete($id) { ... }
}4. CSRF Protection
Cross-Site Request Forgery protection is enabled for all form submissions.
Usage in Forms
<form method="post">
<?= csrf_field() ?>
<!-- form fields -->
</form>AJAX Requests
Include the CSRF token in AJAX headers:
fetch('/api/endpoint', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify(data)
});5. Security Headers
The application sets the following security headers on all responses:
| Header | Value | Purpose |
|---|---|---|
X-Frame-Options | DENY | Prevents clickjacking |
X-Content-Type-Options | nosniff | Prevents MIME sniffing |
X-XSS-Protection | 1; mode=block | XSS filter |
Referrer-Policy | strict-origin-when-cross-origin | Controls referrer info |
6. Infrastructure & Services
The security logic is decoupled into Infrastructure services:
- JwtService (
App\Infrastructure\Auth\Jwt\JwtService): Handles token generation and validation. - SecurityAttributeFilter (
App\Filters\SecurityAttributeFilter): The "Guard" that intercepts requests and enforces attributes.
JwtService Methods
// Generate a token
$token = $jwtService->encode([
'sub' => $userId,
'email' => $userEmail
]);
// Validate and decode
$payload = $jwtService->decode($token);
// Returns: ['sub' => 1, 'email' => 'user@example.com', ...]