Installation
Require the package, generate the RSA key pair for jwt-for-laravel, run the installer and migrate. The service provider is auto-discovered:
composer require roundly-consulting/auth-for-laravel
php artisan jwt:generate-keys
php artisan authentication:install
php artisan migrateauthentication:install publishes the package config and migrations together with the migrations of refresh-tokens-for-laravel, two-factor-for-laravel and passkeys-for-laravel, then prints the wiring below. It never edits your config files.
Publish tags
| Tag | Publishes |
|---|---|
authentication-config | config/authentication.php |
authentication-migrations | The four auth_* tables plus a stub that adds the account columns and passkey_user_handle to the default guard’s table. |
authentication-translations | lang/vendor/authentication — error messages, validation and notification copy. |
Migrations are publish-only — the package never loads them, so publish (or run the installer) before you migrate.
Wire the guard
Each guard needs a jwt guard with its own audience and the authentication user provider in config/auth.php:
// config/auth.php
'guards' => [
'users' => ['driver' => 'jwt', 'provider' => 'users', 'audience' => env('JWT_USERS_AUDIENCE', 'app-users')],
'clients' => ['driver' => 'jwt', 'provider' => 'clients', 'audience' => env('JWT_CLIENTS_AUDIENCE', 'app-clients')],
],
'providers' => [
'users' => ['driver' => 'authentication', 'guard' => 'users'],
'clients' => ['driver' => 'authentication', 'guard' => 'clients'],
],In config/jwt.php, make every jwt guard use the token-version resolver — without it, invalidation revokes nothing:
// config/jwt.php
'guard' => [
'token_version' => \RoundlyConsulting\Auth\Support\TokenVersionResolver::class,
// …
],Prepare the model
The guard model implements the contracts of the features the guard uses:
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use RoundlyConsulting\Auth\Concerns\HasAuthentication;
use RoundlyConsulting\Auth\Contracts\Account;
use RoundlyConsulting\Passkeys\Concerns\InteractsWithPasskeys;
use RoundlyConsulting\Passkeys\Contracts\HasPasskeys;
use RoundlyConsulting\RefreshTokens\Traits\HasRefreshTokens;
use RoundlyConsulting\TwoFactor\Concerns\HasTwoFactorAuthentication;
use RoundlyConsulting\TwoFactor\Contracts\TwoFactorAuthenticatable;
class User extends Authenticatable implements Account, HasPasskeys, TwoFactorAuthenticatable
{
use HasAuthentication, HasRefreshTokens, HasTwoFactorAuthentication, InteractsWithPasskeys, Notifiable;
protected function casts(): array
{
return [...$this->authenticationCasts(), ...$this->twoFactorCasts(), 'email_verified_at' => 'datetime'];
}
}The published stub adds the authentication columns and the passkey user handle (passkey_user_handle, skipped when the table already has it) to the default guard’s table; two-factor’s own stub (two-factor-migrations) adds the TOTP columns, so a fresh install passes authentication:check. Every other guard table calls $table->authenticationColumns() (plus $table->twoFactorColumns() and $table->passkeyUserHandle() when those features are on) — php artisan authentication:guard clients scaffolds the model, migration and factory for you.
Run the doctor
php artisan authentication:checkThe doctor checks every config rule, the provider wiring, the required columns, the JWT keys, the access-token revoker, mail and routes, and exits with code 1 on any error.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.