Hashids
The HashidsConfirmation
service creates tokens that includes the user id, expire date, and a checksum using the Hashids library.
composer require hashids/hashids
Setup
use Jasny\Auth\Auth;
use Jasny\Auth\Authz;
use Jasny\Auth\Confirmation\HashidsConfirmation;
$secret = base64_decode(getenv('AUTH_CONFIRMATION_SECRET')); // Secret is a base64 encoded random 32 byte string
$confirmation = new HashidsConfirmation($secret);
$levels = new Authz\Levels(['user' => 1, 'admin' => 20]);
$auth = new Auth($levels, new AuthStorage(), $confirmation);
Security
The token doesn’t depend on hashids for security, since hashids is not a true encryption algorithm. While the user id and expire date are obfuscated for a casual user, a hacker might be able to extract this information.
The token contains a SHA-256 checksum. This checksum use HMAC with a confirmation secret. To keep others from generating tokens, a strong secret must be used. Make sure the confirmation secret is sufficiently long, like 32 random characters. A short secret might be guessed through brute forcing. Generating a strong secret can be done by running
php -r 'echo base64_encode(random_bytes(32));'
It’s recommended to configure the secret through an environment variable and not put it in your code.
Custom encoding of uid
By default, user IDs are treated as a (binary) string. Encoding them simply takes the byte values and convert it into a hexadecimal value using unpack('H*', $uid)
.
However, if the uid has a specific format (eg an auto-incrementing integer or a UUID) it can be encoded more efficiently, resulting in a shorter hashid token.
use Ramsey\Uuid\Uuid;
$encodeUuid = function (string $uid) {
return bin2hex(Uuid::fromString($uid)->getBytes());
}
$decodeUuid = function (string $hex) {
return Uuid::fromBytes(hex2bin($hex))->toString();
}
$confirmation = (new HashidsConfirmation(getenv('AUTH_CONFIRMATION_SECRET')))
->withUidEncoded($encodeUuid, $decodeUuid);