rafalmasiarek / authkit
Lightweight and extensible PHP authentication library
Requires
- php: >=8.0
- ext-pdo: *
- ramsey/uuid: ^4.9
Requires (Dev)
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-07-11 00:55:46 UTC
README
AuthKit is a lightweight and extensible PHP authentication library supporting:
- User registration and login with hashed passwords
- Secure session-based token authentication (with optional TTL)
- Hook system for extending behavior (audit logs, IP bans, custom rules)
- Support for custom user fields (e.g.
active
,name
, etc.) - Pluggable storage backend (PDO included)
๐ Installation
composer require yourvendor/authkit
Or clone and load via autoloader if not using Composer.
๐ฆ Structure
AuthKit\Auth
โ Main class for authentication operationsAuthKit\User
โ Represents an authenticated userAuthKit\Storage\UserStorageInterface
โ Pluggable storage contractAuthKit\Storage\PdoUserStorage
โ Default PDO storageAuthKit\Hook\HookInterface
โ Optional hook callbacksAuthKit\Message\MessageProviderInterface
โ Customizable messages
๐ง Configuration
use AuthKit\Auth; use AuthKit\Storage\PdoUserStorage; use App\MyHook; $auth = new Auth( new PdoUserStorage($pdo), new MyHook(), // Optional: implements HookInterface 3600 // Token TTL in seconds (0 = no expiry) );
๐ง API Reference
register(string $email, string $password, array $customFields = [], array $additionalChecks = []): User|string
Registers a new user.
- Returns
User
object on success - Returns
string
error message on failure (or throwsAuthException
ifthrowExceptions
istrue
) customFields
: Any user-defined fields (e.g.name
,active
)additionalChecks
: Custom validations ascallable($email, $password, $fields): true|string
login(string $email, string $password, array $additionalChecks = []): string|null
Logs in the user and returns a session token.
- Validates password and optionally runs custom
callable(User): true|string
checks - Returns
string
token ornull
logout(): void
Logs the user out by removing the token from session and storage.
getUser(): ?User
Returns the currently authenticated user or null
. Automatically checks token expiration and triggers hook if session expired.
isLoggedIn(): bool
Shortcut for checking if getUser()
returns a valid user.
updateUser(User $user, array $updates): User
Updates fields for a given user and triggers onUserUpdated()
hook.
๐ช Hook Interface (Optional)
You can implement HookInterface
to extend functionality:
interface HookInterface { public function onBeforeRegister(string $email, string $password, array $fields): true|string; public function onRegisterSuccess(User $user): void; public function onRegisterFailure(string $email, Throwable $e): void; public function onLoginSuccess(User $user): void; public function onLoginFailure(string $email, AuthException $e): void; public function onBeforeLogin(User $user): true|string; public function onLogout(User $user): void; public function onLogoutExpired(): void; public function onUserUpdated(User $user, array $changedFields): void; }
๐งช Example Usage
use AuthKit\Auth; use AuthKit\Storage\PdoUserStorage; $pdo = new PDO('sqlite:/tmp/mydb.sqlite'); $auth = new Auth(new PdoUserStorage($pdo)); $result = $auth->register("foo@example.com", "Password123!", ['name' => 'Foo']); if ($result instanceof \AuthKit\User) { echo "Registered!"; } else { echo "Error: $result"; }
๐ Security Features
- Password hashing with
password_hash()
- Session token with optional expiration (TTL)
- Hook-based IP/fingerprint/session verification
๐ก Advanced Hook Example โ Brute Force & Password Strength
use AuthKit\User; use AuthKit\Hook\AbstractHook; use AuthKit\Exception\AuthException; use PDO; class MyHook extends AbstractHook { private PDO $pdo; public function __construct(PDO $pdo) { $this->pdo = $pdo; } public function onBeforeRegister(string $email, string $password, array $fields): true|string { if (strlen($password) < 12) return "Password must be at least 12 characters."; if (!preg_match('/[A-Z]/', $password)) return "Password must include an uppercase letter."; if (!preg_match('/\d/', $password)) return "Password must include at least one number."; if (!preg_match('/[\W_]/', $password)) return "Password must include a special character."; return true; } public function onBeforeLogin(User $user): true|string { $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $stmt = $this->pdo->prepare("SELECT COUNT(*) FROM login_attempts WHERE ip = :ip AND created_at > datetime('now', '-10 minutes')"); $stmt->execute(['ip' => $ip]); $attempts = (int)$stmt->fetchColumn(); if ($attempts >= 5) { return "Too many failed login attempts. Please wait 10 minutes."; } return true; } public function onLoginFailure(string $email, AuthException $e): void { $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $stmt = $this->pdo->prepare("INSERT INTO login_attempts (ip, email, created_at) VALUES (:ip, :email, :ts)"); $stmt->execute([ 'ip' => $ip, 'email' => $email, 'ts' => date('Y-m-d H:i:s') ]); } public function onLoginSuccess(User $user): void { $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown'; $this->pdo->prepare("DELETE FROM login_attempts WHERE ip = :ip")->execute(['ip' => $ip]); } }
๐ Directory Structure
src/
โโโ Auth.php
โโโ User.php
โโโ Hook/
โ โโโ HookInterface.php
โ โโโ AbstractHook.php
โโโ Message/
โ โโโ MessageProviderInterface.php
โ โโโ DefaultMessageProvider.php
โโโ Storage/
โ โโโ PdoUserStorage.php
โ โโโ UserStorageInterface.php
โโโ Exception/
โโโ AuthException.php
๐ Custom Storage Layer
To use your own storage system, implement UserStorageInterface
:
interface UserStorageInterface { public function findByEmail(string $email): ?User; public function findByToken(string $token): ?User; public function createUser(string $email, string $passwordHash, array $fields = []): User; public function storeToken(User $user, string $token, ?DateTime $expiresAt): void; public function updateUser(User $user, array $updates): User; public function deleteToken(string $token): void; }
๐งโ๐ป License
MIT License.