A Laravel package for Time-based One-Time Password (TOTP) authentication with Blade shortcode support and optional QR code display.
- TOTP generation and verification using
spomky-labs/otphp. - Encrypted secrets stored via Laravel Crypt.
- Per-client secrets with active scope and last-used tracking.
- Blade directive
@totp([...])to render current code with timer. - Configurable period, digits, algorithm, window, QR settings.
- Tested with Pest + Orchestra Testbench.
- PHP: ^8.3
- Laravel: ^10 || ^11 || ^12
- Install via Composer:
composer require sanjay-np/laravel-authenticator- Publish only what you need (config or migration):
- Publish config only:
php artisan vendor:publish --tag=laravel-authenticator-config- Publish migration only:
php artisan vendor:publish --tag=laravel-authenticator-migrationsThis will place:
- Config at
config/authenticator.php - Migration (timestamped) under
database/migrations
- Run migrations:
php artisan migrateUpdate config/authenticator.php as needed:
- totp.period: default 60 seconds
- totp.digits: default 6
- totp.algorithm:
sha1|sha256|sha512 - totp.window: allowed drift windows for verification
use LaravelAuthenticator\LaravelAuthenticator;
$auth = app(\LaravelAuthenticator\LaravelAuthenticator::class);
// Create a secret for a client (e.g., user id)
$record = $auth->generateClientSecret(clientId: 123, label: 'My Device');
// Get current TOTP code
$code = $auth->getCurrentCode($record->secret);
// Verify a code
$isValid = $auth->verifyCode($record->secret, $code);
// Verify by client id via model lookup
$isValid = $auth->verifyTotpCode(123, $code);
// Data for UI display (timer, progress, etc.)
$data = $auth->getClientTotpDisplayData($record->id);use LaravelAuthenticator\Facades\LaravelAuthenticator;
$secret = LaravelAuthenticator::generateSecret();Render a live-updating code with a progress timer (auto-refresh via page reload each period):
@totp(['secret_id' => $secretId, 'display' => 'code', 'show_timer' => 'true'])- secret_id: the
authenticator_secrets.idvalue - display:
code|qr|both|minimal(currentlycodeis implemented) - show_timer:
true|false
Table: authenticator_secrets
- client_id: bigint (application user id or similar)
- secret: encrypted string via
Crypt - label, issuer, algorithm, digits, period, is_active, last_used_at
A migration is provided and can be published using the commands above. Ensure APP_KEY is set.
This package ships with Pest tests.
- Run all tests:
composer test- With coverage:
composer test-coverage- Secrets are encrypted at rest using Laravel Crypt.
- Ensure APP_KEY is configured in production.
- Consider rotating secrets if compromised and track
last_used_at. - Limit exposure of raw secrets;
getClientTotpDisplayDatahides secrets by default.
- Follow SemVer:
MAJOR.MINOR.PATCH. - Add changes to a
CHANGELOG.md. - Tag releases in Git:
git tag vX.Y.Z && git push --tags. - Configure GitHub Actions (optional) to run tests and build on PRs.
Create .github/workflows/tests.yml:
name: tests
on: [push, pull_request]
jobs:
pest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
coverage: xdebug
- run: composer install --no-interaction --prefer-dist
- run: composer test-coverageMIT