API Library
The Api library provides helper methods for building secure RESTful APIs in LavaLust.
It supports:
CORS headers
Parsing JSON/form bodies
Standard API responses
JWT-based authentication (access/refresh token system)
Basic authentication
Refresh token encryption and storage
This library is automatically configured using values from app/config/api.php.
Folder Structure
app/
├── controllers/
│   └── ApiController.php
│
└── config/
    └── api.php
Configuration
Set the following values in app/config/api.php:
<?php
$config['api_helper_enabled'] = FALSE;
$config['payload_token_expiration'] = 900;
$config['refresh_token_expiration'] = 604800;
$config['jwt_secret'] = 'l99H8TM4Q4JXFM3Hr8LN';
$config['refresh_token_key'] = 'BDswlrEaYWAgeJ4VurGe';
$config['allow_origin'] = '*';
$config['refresh_token_table'] = 'refresh_tokens';
Properties
Property  | 
Type  | 
Description  | 
|---|---|---|
  | 
object  | 
LavaLust super object (via   | 
  | 
string  | 
Database table name for storing refresh tokens  | 
  | 
integer  | 
Lifetime of access (payload) tokens in seconds  | 
  | 
integer  | 
Lifetime of refresh tokens in seconds  | 
  | 
string  | 
Allowed origin for CORS  | 
  | 
string  | 
Secret key used for signing JWT tokens  | 
  | 
string  | 
Key used for encrypting refresh tokens  | 
Methods
CORS & Request Helpers
Method  | 
Description  | 
|---|---|
  | 
Sets CORS headers. Called automatically in the constructor.  | 
  | 
Parses JSON or form-encoded request body and returns it as an array.  | 
  | 
Returns URL query parameters as an associative array.  | 
  | 
Enforces a specific HTTP method. Sends 405 if not matched.  | 
Responses
Method  | 
Description  | 
|---|---|
  | 
Sends a JSON response with HTTP status code.  | 
  | 
Sends an error response with a message and status code.  | 
JWT Authentication
Method  | 
Description  | 
|---|---|
  | 
Encodes data into a signed JWT.  | 
  | 
Decodes and verifies a JWT.  | 
  | 
Validates structure and expiration of a JWT.  | 
  | 
Extracts a JWT bearer token from the   | 
  | 
Validates the current bearer token and returns its payload.  | 
Token System
Method  | 
Description  | 
|---|---|
  | 
Issues an access token and a refresh token, stores the refresh token in the database.  | 
  | 
Validates and rotates a refresh token, issues new tokens.  | 
  | 
Deletes a refresh token from the database.  | 
  | 
Deletes expired refresh tokens for a user.  | 
Basic Authentication
Method  | 
Description  | 
|---|---|
  | 
Verifies provided basic auth credentials.  | 
  | 
Requires valid basic auth, otherwise sends a 401 Unauthorized response.  | 
Database Structure
Table: ``users``
Column  | 
Type  | 
Null  | 
Default  | 
Description  | 
|---|---|---|---|---|
id  | 
INT(11) PK AI  | 
NO  | 
AUTO_INCREMENT  | 
Primary key  | 
username  | 
VARCHAR(50) UNIQUE  | 
NO  | 
—  | 
Username of the user  | 
VARCHAR(100) UNIQUE  | 
NO  | 
—  | 
Email address of the user  | 
|
password  | 
VARCHAR(255)  | 
NO  | 
—  | 
Hashed password  | 
role  | 
VARCHAR(20)  | 
YES  | 
‘user’  | 
User role (default: user)  | 
created_at  | 
TIMESTAMP  | 
YES  | 
CURRENT_TIMESTAMP  | 
Record creation time  | 
Table: ``refresh_tokens``
Column  | 
Type  | 
Description  | 
|---|---|---|
id  | 
INT PK AI  | 
Primary key  | 
user_id  | 
INT  | 
Associated user ID  | 
token  | 
TEXT  | 
Encrypted refresh token  | 
expires_at  | 
DATETIME  | 
Expiration date of the refresh token  | 
Controller Example
Routes
<?php
$router->post('login', 'ApiController::login');
$router->post('logout', 'ApiController::logout');
$router->post('create', 'ApiController::create');
$router->put('update/{id}', 'ApiController::update');
$router->delete('delete/{id}', 'ApiController::delete');
$router->get('list', 'ApiController::list');
$router->get('profile', 'ApiController::profile');
$router->post('refresh', 'ApiController::refresh');
Controller
<?php
class ApiController extends Controller {
    private $user_id;
    public function login() {
        $this->api->require_method('POST');
        $input = $this->api->body();
        $username = $input['username'] ?? '';
        $password = $input['password'] ?? '';
        $stmt = $this->db->raw('SELECT * FROM users WHERE username = ?', [$username]);
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($user && password_verify($password, $user['password'])) {
            $tokens = $this->api->issue_tokens(['id' => $user['id'], 'role' => $user['role']]);
            $this->api->respond($tokens);
        } else {
            $this->api->respond_error('Invalid credentials', 401);
        }
    }
    public function logout() {
        $this->api->require_method('POST');
        $input = $this->api->body();
        $token = $input['refresh_token'] ?? '';
        $this->api->revoke_refresh_token($token);
        $this->api->respond(['message' => 'Logged out']);
    }
    public function list() {
        $stmt = $this->db->table('users')
                         ->select('id, username, email, role, created_at')
                         ->get_all();
        $this->api->respond($stmt);
    }
    public function create() {
        $input = $this->api->body();
        $this->db->raw(
            "INSERT INTO users (username, email, password, role, created_at)
             VALUES (?, ?, ?, ?, NOW())",
            [$input['username'], $input['email'], password_hash($input['password'], PASSWORD_BCRYPT), $input['role']]
        );
        $this->api->respond(['message' => 'User created']);
    }
    public function update($id) {
        $input = $this->api->body();
        $this->db->raw("UPDATE users SET username=?, email=?, role=? WHERE id=?",
            [$input['username'], $input['email'], $input['role'], $id]);
        $this->api->respond(['message' => 'User updated']);
    }
    public function delete($id) {
        $this->db->raw("DELETE FROM users WHERE id = ?", [$id]);
        $this->api->respond(['message' => 'User deleted']);
    }
    public function profile() {
        $auth = $this->api->require_jwt();
        $this->user_id = $auth['sub'];
        $stmt = $this->db->raw(
            "SELECT id, username, email, role, created_at FROM users WHERE id = ?",
            [$this->user_id]
        );
        $user = $stmt->fetch(PDO::FETCH_ASSOC);
        $this->api->respond($user ?: ['message' => 'User not found']);
    }
    public function refresh() {
        $this->api->require_method('POST');
        $input = $this->api->body();
        $refresh_token = $input['refresh_token'] ?? '';
        $this->api->refresh_access_token($refresh_token);
    }
}
Using Postman with PHP API Controller
This guide shows how to test each endpoint of your PHP API using Postman, either in VS Code (via Postman extension) or the standalone Postman app.
Note
Use your actual base URL (e.g. http://localhost/ApiController/...) when testing.
Login
Endpoint:
POST /ApiController/login
Request Body:
{
  "username": "admin",
  "password": "your_password"
}
Expected Response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6..."
}
Logout
Endpoint:
POST /ApiController/logout
Request Body:
{
  "refresh_token": "your_refresh_token"
}
Expected Response:
{
  "message": "Logged out"
}
List Users
Endpoint:
GET /ApiController/list
Headers:
Authorization: Bearer your_access_token
Expected Response:
[
  {
    "id": 1,
    "username": "admin",
    "email": "admin@example.com",
    "role": "admin",
    "created_at": "2025-08-01 12:00:00"
  },
  ...
]
Create User
Endpoint:
POST /ApiController/create
Headers:
Authorization: Bearer your_access_token
Content-Type: application/json
Request Body:
{
  "username": "newuser",
  "email": "newuser@example.com",
  "password": "secure123",
  "role": "user"
}
Update User
Endpoint:
PUT /ApiController/update/{id}
Headers:
Authorization: Bearer your_access_token
Content-Type: application/json
Request Body:
{
  "username": "updateduser",
  "email": "updated@example.com",
  "role": "editor"
}
Delete User
Endpoint:
DELETE /ApiController/delete/{id}
Headers:
Authorization: Bearer your_access_token
Profile
Endpoint:
GET /ApiController/profile
Headers:
Authorization: Bearer your_access_token
Refresh Token
Endpoint:
POST /ApiController/refresh
Request Body:
{
  "refresh_token": "your_refresh_token"
}
Tips
Use Postman collections to save all these endpoints.
Use environment variables for
{{base_url}},{{access_token}}, and{{refresh_token}}to streamline testing and token management.
Note
Notes
- Configure values such as jwt_secret, refresh_token_key, and expiration times in app/config/api.php.
- CORS is automatically handled on every request.
- OPTIONS requests are automatically responded with 200 and exit.
Api library simplifies authentication, token management, and secure API development in LavaLust.