Installation
Require the package and publish the config. The service provider and the Jwt facade alias are auto-discovered — no manual registration:
composer require roundly-consulting/jwt-for-laravel
php artisan vendor:publish --tag="jwt-config"jwt-config is the only publish tag — there are no migrations, views or routes. The provider binds every contract to its native implementation, registers the jwt and service-jwt guard drivers and adds the jwt:generate-keys command.
Issuer apps
An issuer app mints user tokens, so it holds the RSA private key. Set the pins, then generate a 2048-bit keypair:
# Pinned into and checked on every user token.
JWT_ISSUER=auth
JWT_AUDIENCE=web
# Optional: the key paths default to storage/jwt-private.key and storage/jwt-public.pem.
# Relative paths resolve from the application root.
# JWT_PRIVATE_KEY_PATH=storage/jwt-private.key
# JWT_PUBLIC_KEY_PATH=storage/jwt-public.pemphp artisan jwt:generate-keysWith no JWT_* key paths set, it writes the private key to storage/jwt-private.key (mode 0600) and the public key to storage/jwt-public.pem — exactly where the config reads them. A stock Laravel .gitignore already excludes /storage/*.key; if you point JWT_PRIVATE_KEY_PATH elsewhere, keep that file out of version control yourself. Relative paths resolve against the application root.
Verify-only apps
Every other service only verifies. Copy the issuer’s public key to JWT_PUBLIC_KEY_PATH (default storage/jwt-public.pem) — no private key is needed, because only minting reads it, so the private key never leaves the issuer:
JWT_ISSUER=auth
JWT_AUDIENCE=web
# No private key. Copy the issuer's public key here.
JWT_PUBLIC_KEY_PATH=storage/jwt-public.pemJWT_ISSUER and JWT_AUDIENCE are required on both sides. A value that is not set (null or blank) throws JwtMisconfigured as soon as the issuer or verifier is resolved, so an unset pin can never match vacuously.
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.