Security API – Security Class
The Security class provides a complete authentication, authorisation and protection toolkit. It covers user login/logout, session management, permissions, owner‑based row‑level security, password hashing, CSRF, rate limiting, TOTP two‑factor authentication and secure "Remember Me" cookies. Every method is static and safe – no manual session manipulation needed.
Contents
- Authentication – Login, Logout, LoginAs
- User State – IsLoggedIn, IsAdmin, CurrentUser*, etc.
- Auth Guards – RequireAuth, RequireRole
- Table‑level Permissions
- Allowed Pages
- OwnerID (Row‑level Security)
- Password Utilities
- Remember Me
- CSRF Protection
- Rate Limiting
- Two‑factor Authentication (TOTP)
- Display Name
- Secure Token Generation
Authentication
Login – Standard username/password
// Basic login
if (Security::Login($username, $password)) {
echo "Welcome, " . Security::CurrentUsername();
} else {
echo "Invalid credentials.";
}
Login with “Remember Me”
// Pass true to set a persistent cookie (30 days)
Security::Login($username, $password, true);
Login without password (e.g. after OAuth)
// LoginAs only needs a username – no password check
Security::LoginAs('john.doe');
Check credentials without logging in
if (Security::CheckUsernamePassword('admin', 'secret')) {
// valid, but session is unchanged
}
Logout
Security::Logout();
// After logout, all session data is removed.
// You should redirect to the login page.
header('Location: /login');
User State
// Is anybody logged in?
if (Security::IsLoggedIn()) { … }
// Is the current user a superadmin?
if (Security::IsAdmin()) { … }
// Is the visitor a guest?
if (Security::IsGuest()) { … }
// Get the username
echo Security::CurrentUsername(); // e.g. "john.doe"
// Get the role/group
echo Security::CurrentUserGroup(); // "superadmin", "developer", "user"
// Get all groups (array) – currently wraps role in an array
$groups = Security::CurrentUserGroups();
// Full user data array (cached in session)
$user = Security::CurrentUserData();
echo $user['email'];
// Reload user data from database
Security::RefreshUserData();
Table‑level Permissions
Each table has seven permission bits: Add, Delete, Edit, Search/List, Print/Export, Import, Manage (admin).
Set permissions for a table
// Using a string (each letter grants the corresponding right)
Security::SetPermissions('orders', 'ADES'); // can add, delete, edit, search
// Using an array
Security::SetPermissions('products', [
'A' => true,
'D' => false,
'E' => true,
'S' => true,
'P' => true,
'I' => false,
'M' => false
]);
Check a specific permission
if (Security::HasPermission('orders', 'E')) {
echo "User can edit orders.";
} else {
echo "Edit access denied.";
}
Retrieve all permissions for a table
$perms = Security::GetPermissions('orders');
if ($perms['A']) { echo "Can add"; }
Allowed Pages
Fine‑grained control over which individual pages a user can access for a table and page type (list, add, edit, view, print, search).
Set allowed pages
// Allow only the "summary" and "details" pages for the list type
Security::SetAllowedPages('orders', 'list', ['summary', 'details']);
// A single page as a string
Security::SetAllowedPages('orders', 'add', 'order_add');
Get allowed pages
$pages = Security::GetAllowedPages('orders', 'list');
if (in_array('summary', $pages)) {
echo "Summary page is allowed.";
}
OwnerID (Row‑level Security)
When a table has “own data only” security, the system needs to know which ID belongs to the current user. OwnerID stores that value.
Set OwnerID
// After login, set the user's ID as the owner for the customers table
Security::SetOwnerId('customers', $user['id']);
Get OwnerID
$ownerId = Security::GetOwnerId('customers');
DB::Select('customers', ['assigned_to' => $ownerId]);
Password Utilities
Hash a password
$hashed = Security::HashPassword('mySecureP@ss');
// Uses bcrypt (PASSWORD_DEFAULT)
Verify a password
if (Security::VerifyPassword('mySecureP@ss', $hashed)) {
// valid
}
Check if a hash needs rehashing
if (Security::PasswordNeedsRehash($hashed)) {
$newHash = Security::HashPassword($newPassword);
DB::Update('users', ['password' => $newHash], ['id' => $userId]);
}
Remember Me
// When logging in with rememberMe = true, a long‑lived cookie is set.
Security::Login($username, $password, true);
// On subsequent visits, before any authentication check:
if (!Security::IsLoggedIn() && Security::LoginFromRememberMe()) {
// User was logged in via cookie; session is now active.
}
CSRF Protection
// Generate a CSRF token (stored in session)
$token = Security::CSRF()->Token();
// Output a hidden field in a form
echo Security::CSRF()->HiddenField();
// Check a submitted token
if (!Security::CSRF()->Check($_POST['_token'] ?? '')) {
die('Invalid CSRF token.');
}
// Regenerate token (e.g. after login)
Security::CSRF()->Regenerate();
Check() method uses hash_equals() for timing‑safe comparison.
Rate Limiting
// Protect a login endpoint from brute‑force attacks
$key = 'login:' . $_SERVER['REMOTE_ADDR'];
$maxAttempts = 5;
$window = 60; // 60 seconds
if (!Security::RateLimit()->Check($key, $maxAttempts, $window)) {
$remaining = Security::RateLimit()->Remaining($key, $maxAttempts, $window);
die("Too many attempts. Try again in $window seconds.");
}
// After a failed login:
Security::RateLimit()->Hit($key);
// After a successful login, you can clear the rate limit:
// (Manually unset the session key or wait for the window to expire)
Two‑factor Authentication (TOTP)
// Generate a secret for a user
$secret = Security::TOTP()->GenerateSecret(); // e.g. "JBSWY3DPEHPK3PXP"
DB::Update('users', ['totp_secret' => $secret], ['id' => $userId]);
// Get the QR code URL (for apps like Google Authenticator)
$qrUrl = Security::TOTP()->GetQRCodeUrl($username, $secret, 'MyApp');
// Display as a QR image using a service or JavaScript library
// Verify a code entered by the user
$code = $_POST['totp_code']; // 6 digits
if (Security::TOTP()->Verify($secret, $code)) {
echo "Code is valid!";
} else {
echo "Invalid code.";
}
// Verify with a wider time drift (±2 periods, ±60 seconds)
Security::TOTP()->Verify($secret, $code, 2);
Display Name
// Get the current user's display name
echo Security::GetDisplayName(); // returns fullname, or username as fallback
// Set a custom display name in the session (temporary)
Security::SetDisplayName('John (Admin)');
Secure Token Generation
// Generate a cryptographically secure random token (hex)
$token = Security::GenerateToken(); // 64 hex chars (32 bytes)
$shortToken = Security::GenerateToken(16); // 32 hex chars (16 bytes)
// Use for CSRF, password resets, invitation links, etc.
Auth Guards – RequireAuth, RequireRole
These are shortcut methods that immediately stop the request if the user is not authenticated or lacks the required role. They replace the repetitive guard code that was previously duplicated in every controller.
RequireAuth()
Redirects to the login page if the user is not logged in. Use it at the top of any protected method.
// Protect a whole controller method
public function listProjects(): void {
Security::RequireAuth();
// ... your code here
}
RequireRole(array $roles)
Stops with a 403 Forbidden message if the current user's role is not in the allowed list.
// Only superadmin and developer can create projects
Security::RequireRole(['superadmin', 'developer']);
Combined example
public function createProject(): void {
Security::RequireAuth();
Security::RequireRole(['superadmin', 'developer']);
// proceed with project creation...
}