Secure, lightweight PHP library for creating cryptographically signed tokens with built-in expiration and validation. Supports any PHP hash algorithm for flexible performance and security trade-offs. Perfect for API authentication, session management, temporary access grants, and distributed systems requiring tamper-proof tokens without external dependencies.
composer require antikirra/token:^1.0- 🔒 Cryptographically Secure - HMAC-based signatures prevent tampering and forgery
- ⏰ Built-in Expiration - Native timestamp-based expiration with microsecond precision
- 🎯 Type-Safe Design - Strongly typed tokens with customizable type identifiers (1-255)
- 🔧 Algorithm Flexibility - Support for any PHP hash algorithm (xxHash, SHA-3, BLAKE2, etc.)
- 📦 Compact Encoding - Efficient binary packing with URL-safe Base64 encoding
- ✅ Signature Verification - Constant-time hash comparison prevents timing attacks
- 🚀 Production Ready - Battle-tested with comprehensive boundary testing
- 🧪 Fully Tested - Extensive test coverage with Pest test suite
- 🔄 Serialization Support - Built-in PHP serialization with validation
- 🛡️ Clone Protection - Prevents token cloning for enhanced security
- Cryptographic Signatures: HMAC-based signing with customizable salt and hash algorithms
- Expiration Management: Built-in timestamp validation with timezone support
- Type System: 255 distinct token types for multi-purpose authentication systems
- Identity Binding: Supports 64-bit integer identities (up to 18,446,744,073,709,551,615)
- Nonce Generation: Cryptographically secure random nonce (268,435,456 to 4,294,967,295)
- Binary Efficiency: Compact binary packing reduces token size by ~40% vs JSON
- URL-Safe Encoding: Base64url encoding compatible with URLs and HTTP headers
- Tamper Detection: Constant-time signature verification with hash_equals()
- Strict Validation: Comprehensive input validation with clear error messages
- Zero Configuration: Works out of the box, extend and configure as needed
- Memory Efficient: Minimal memory footprint with readonly properties
- API Authentication: Stateless authentication tokens with built-in expiration
- Session Management: Secure session identifiers with tamper protection
- Temporary Access: Time-limited resource access grants and one-time tokens
- OAuth/JWT Alternative: Lightweight alternative for internal authentication systems
- Password Reset Tokens: Secure, expiring tokens for password recovery flows
- Email Verification: Tamper-proof verification tokens with expiration
- Download Links: Time-limited, signed download URLs
- Invitation Systems: Secure invitation tokens with type-based permissions
- Multi-Tenant Systems: Type-based token segregation for different services
- Microservices: Service-to-service authentication without shared state
- PHP: 8.1 or higher
- Extensions:
ext-mbstring- For byte-safe string operations
- Dependencies:
antikirra/base64url- URL-safe Base64 encoding/decoding
<?php
declare(strict_types=1);
use Antikirra\Token;
require __DIR__ . '/vendor/autoload.php';
// Define your token class with custom configuration
final class MySecretToken extends Token
{
protected static function type(): int
{
// Token type in the range from 1 to 255
return 1;
}
protected static function salt(): string
{
// !!! DO NOT MODIFY AFTER SETUP !!!
// Minimum 32 bytes required for security
return '4Q8myx0n8mrdLs6ZdEvpp9ekV78nhn5P4ruf9Z96tu4ZEVlmWeGawymg3W0mkgPj';
}
protected static function algorithm(): string
{
// Any algorithm from hash_algos()
// xxh128 is fast and secure for most use cases
return 'xxh128';
}
}
// Create a new token
$token = MySecretToken::create(123456, new DateTimeImmutable('+1 day'));
// Get the encoded token string (URL-safe)
echo (string)$token;
// Output: AQBA4gEAAAAAAPDcoGguuFT3rMY17QZy-gmNOs1dIQWcR
// Decode and verify a token
$decoded = MySecretToken::decode('AQBA4gEAAAAAAPDcoGguuFT3rMY17QZy-gmNOs1dIQWcR');
// Check expiration
if ($decoded->isExpired()) {
echo "Token has expired";
}
// Get token data
echo $decoded->getIdentity(); // 123456
echo $decoded->getExpiredAt()->format('Y-m-d H:i:s');
// Type checking
if ($decoded->typeOf(1)) {
echo "This is a type 1 token";
}
// Serialization support
$serialized = serialize($token);
$unserialized = unserialize($serialized);
echo (string)$unserialized; // Same as original tokenfinal class AccessToken extends Token
{
protected static function type(): int { return 1; }
protected static function salt(): string { return 'your-secret-salt-min-32-bytes-long-string-here'; }
protected static function algorithm(): string { return 'sha3-256'; }
}
final class RefreshToken extends Token
{
protected static function type(): int { return 2; }
protected static function salt(): string { return 'different-salt-for-refresh-tokens-min-32-bytes'; }
protected static function algorithm(): string { return 'sha3-256'; }
}
$access = AccessToken::create(userId: 42, expiredAt: new DateTimeImmutable('+15 minutes'));
$refresh = RefreshToken::create(userId: 42, expiredAt: new DateTimeImmutable('+30 days'));try {
$token = MySecretToken::decode('invalid-token-string');
} catch (RuntimeException $e) {
// Handle invalid token (tampered, malformed, or expired signature)
error_log("Token validation failed: " . $e->getMessage());
}This library is thoroughly tested with comprehensive test coverage:
- 120 tests with 432 assertions
- All tests passing with zero failures
- Test suite execution time: ~0.19s
- TokenTest (13 tests): Core functionality, encoding/decoding, serialization
- AlgorithmBoundaryTest (47 tests): Hash algorithm validation and edge cases
- EdgeCasesTest (19 tests): Edge cases, serialization, boundary conditions
- SaltBoundaryTest (22 tests): Salt size boundaries and validation
- TypeBoundaryTest (19 tests): Token type range validation
- Boundary Tests: Type (1-255), Identity (1 to 2^64-1), Nonce (268,435,456 to 4,294,967,295)
- Salt Validation: Tests for minimum 32-byte requirement and various salt lengths
- Algorithm Support: Validates all common hash algorithms (MD5, SHA family, SHA-3, xxHash, etc.)
- Encode/Decode: Round-trip testing with signature verification
- Serialization: PHP serialize/unserialize with validation
- Expiration: Timestamp validation and timezone handling
- Error Cases: Invalid inputs, tampered signatures, boundary violations
# Run all tests
./vendor/bin/pest
# Run tests with code coverage
./vendor/bin/pest --coverage- Salt Management: NEVER change the salt after deploying tokens - it will invalidate all existing tokens
- Algorithm Choice: Use modern algorithms like
xxh128,sha3-256, orblake2bfor best security/performance balance - Salt Length: Minimum 32 bytes required; recommend 64+ bytes for maximum security
- Token Storage: Never log or expose full tokens; only store hashed versions in databases
- Expiration: Always set reasonable expiration times; avoid long-lived tokens when possible
- HTTPS Only: Always transmit tokens over HTTPS to prevent interception
- Constant-Time Comparison: Built-in
hash_equals()prevents timing attacks
token, authentication, cryptographic-signature, hmac, secure-tokens, api-authentication, session-management, php-8.1, expiration, tamper-proof, stateless-auth, base64url, binary-packing, pest-testing, type-safe