Auth facade and middleware.
This quickstart uses 2D mode, where the Identity and Principal are the same model — the user who logs in is the actor on whose behalf every request runs. This is the right starting point for most apps. If you’re building a multi-tenant product where a single human can act as different tenant-scoped roles, see Adoption Modes for the 3D setup.
Install the package
Add the package via Composer:Publish the config file and the device migration, then run the migration:The migration creates the
devices table used for refresh-token rotation and device tracking. If you only need access tokens and no refresh flow (common for M2M APIs), you can skip authentication-migrations entirely and omit the HasDevices contract from your model.Set the JWT secret
Add your signing secret to Generate a suitable value with
.env. The package fails closed when a JWT guard is resolved with an empty or invalid secret — there is no silent fallback:openssl rand -base64 48 or any equivalent tool. Keep this value out of version control.Register the JWT guard
Open The
config/auth.php and register the jwt driver for your API guard, pointing it at your users provider:jwt driver is registered automatically by the package’s service provider. No additional bootstrapping is required.Implement the Identity model
Your user model needs to implement the A few things to note:
Identity and Principal contracts and pull in the corresponding traits. In 2D mode, the same class satisfies both contracts:StatelessAuthenticatablere-exports Laravel’s ownAuthenticatabletrait, but overrides the remember-token accessors with no-ops — this package is stateless and never writes a remember token.ActsAsPrincipalprovides thegetPrincipalIdentifier()implementation required by thePrincipalcontract, defaulting to the model’s primary key.- Point
auth.providers.users.modelat this class if it isn’t alreadyApp\Models\User.
Issue an access token
In your login controller, verify the user’s credentials and call The returned string is a signed JWT. Your client should store it and include it as a
Auth::jwt('api')->issueAccessToken() to mint a signed JWT. In 2D mode the identity and principal are the same model instance, and you pass null for the device when you’re not tracking devices:Bearer token in the Authorization header on subsequent requests.Protect a route and read context
Use the standard Inside the protected controller, use
auth:api middleware to protect any route. The JWT guard validates the bearer token, rehydrates the identity from your provider, and resolves the principal automatically:Auth::identity() and Auth::principal() to read the contextual values set by the guard. In 2D mode both return the same User instance:Next steps
You now have a working JWT bearer-token guard. From here you can explore:2D setup in depth
Add active-state enforcement, device tracking, and a full login/refresh/logout flow to your 2D app.
Refresh rotation
Issue refresh tokens, implement atomic rotation, and handle replay detection.
Identity, Principal, Device
Understand the three-context model and when each accessor returns what.