Little JWT provides a guard for Laravel that authenticates users using a provided JWT.
The first step to enabling the Little JWT guard is adding the configuration options to the config/auth.php
file:
return [
'guards' => [
'jwt' => [
'driver' => 'littlejwt',
'adapter' => 'fingerprint',
'provider' => 'users',
'input_key' => 'token'
],
],
];
You can set 'jwt'
as the default guard in the config/auth.php
file:
return [
'defaults' => [
'guard' => 'jwt',
],
];
To authenticate a user from a JWT, assign 'auth'
as the middleware for a route:
Route::get('/user', function () {
//
})->middleware('auth');
You can also specify 'jwt'
as the guard to specifically use for authentication (if there's another default guard set):
Route::get('/user', function () {
//
})->middleware('auth:jwt');
Authentication is done using the adapter set in the config/auth.php
file (see 'Adapters' below on how to change the adapter and available adapters).
After the validation passes, the user is retrieved (also by the adapter) and can be retrieved using the Auth
facade:
use Illuminate\Support\Facades\Auth;
$user = Auth::user();
An adapter is attached to the LittleJWT guard to specify how the JWT is validated. It can also specify how the JWT is built.
Set the adapter to be used by the guard in the config/auth.php
file:
return [
'guards' => [
'jwt' => [
'adapter' => 'fingerprint',
],
],
];
The following describes each adapter in more detail, including the validation steps. Little JWT comes with the following adapters:
'generic'
)'fingerprint'
)The generic adapter is intended for building a JWT for a user and validating it. The generic adapter uses the Guard Validatable on top of the Default Validatable.
Set the adapter to generic
in the config/auth.php
file:
return [
'guards' => [
'jwt' => [
'adapter' => 'generic',
],
],
];
The configuration options for the generic adapter are located in the config/littlejwt.php
file. There's currently no configuration options for the generic adapter.
return [
'guard' => [
'adapters' => [
'generic' => [
/**
* The class for the adapter.
* This should not be changed.
*/
'adapter' => \LittleApps\LittleJWT\Guards\Adapters\GenericAdapter::class,
],
],
],
];
A JWT can be be built for a user using the generic adapter from the Auth
facade:
use Illuminate\Support\Facades\Auth;
$jwt = Auth::buildJwtForUser($user);
$token = (string) $jwt;
Additional header and payload claims can also be included:
use Illuminate\Support\Facades\Auth;
$payload = [
'abc' => 'def'
];
$header = [
'abc' => 'def'
];
$jwt = Auth::buildJwtForUser($user, $payload, $header);
$token = (string) $jwt;
A Response
instance can be built from the user:
use Illuminate\Support\Facades\Auth;
$response = Auth::createJwtResponse($user);
The response will be a JSON object as shown on the Request & Response Helpers page.
The fingerprint adapter is meant for building and validating JWTs that are secured against token sidejacking. After the default and guard validatables are used, the fingerprint validatable is used.
Set the adapter to fingerprint
in the config/auth.php
file:
return [
'guards' => [
'jwt' => [
'adapter' => 'fingerprint',
],
],
];
The configuration options for the fingerprint adapter are located in the config/littlejwt.php
file:
return [
'guard' => [
'adapters' => [
'fingerprint' => [
/**
* The class for the adapter.
* This should not be changed.
*/
'adapter' => \LittleApps\LittleJWT\Guards\Adapters\FingerprintAdapter::class,
/**
* Name of the cookie to hold the fingerprint.
*/
'cookie' => 'fingerprint',
/**
* How long the fingerprint cookie should live for (in minutes).
* If 0, the cookie has no expiry.
*/
'ttl' => 0,
],
],
],
];
A fingerprint is a unique UUID that's stored as a cookie and passed along with a JWT (which contains a hash of the fingerprint).
You can generate a JWT with a random fingerprint and have the cookie automatically included in the response:
use Illuminate\Support\Facades\Auth;
$response = Auth::createJwtResponse($user);
The response will be a JSON object (the same shown in the Request & Response Helpers page) and include a cookie containing the fingerprint.
You can manually send the JWT and/or cookie yourself:
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\Str;
// Generate the fingerprint UUID
$fingerprint = (string) Str::uuid();
// Hash the fingerprint UUID
$hash = Auth::hashFingerprint($fingerprint);
// Generate the JWT with the fingerprint hash
$jwt = Auth::createJwtWithFingerprint($user, $hash);
// Respond with information about the JWT and fingerprint cookie
return
Response::withJwt($jwt)
->withCookie(Auth::getFingerprintCookieName(), $fingerprint, Auth::getFingerprintCookieTtl());
The following is a list of steps done by this adapter to validate the JWT:
A custom guard adapter can be created to incorporate your own validation checks.
Define a class that provides the validation functionality for the guard using one of the following options:
AbstractAdapter
The AbstractAdapter
class provides the needed functionality to parse a token, validate a JWT, and get the associated User model (using the sub
payload claim).
Create a class that extends AbstractAdapter
and in the getValidatorCallback
method, return a callback that sets the Validator rules:
use LittleApps\LittleJWT\Guards\Adapters\AbstractAdapter;
use LittleApps\LittleJWT\Validation\Validator;
class MyAdapter extends AbstractAdapter {
/**
* Gets a callback that receives a Validator to specify the JWT validations.
*
* @return callable
*/
protected function getValidatorCallback()
{
return function(Validator $validator) {
// ...
};
}
}
The LittleJWT handler used by the adapter can be changed. This is useful if mutators should be set. This is done by overriding the getHandler
method (provided by AbstractAdapter
):
use LittleApps\LittleJWT\Guards\Adapters\AbstractAdapter;
use LittleApps\LittleJWT\LittleJWT;
use LittleApps\LittleJWT\Mutate\Mutators;
class MyAdapter extends AbstractAdapter {
// ...
/**
* Gets the LittleJWT handler
*
* @return \LittleApps\LittleJWT\Core\Handler
*/
protected function getHandler() {
return
$this->container->make(LittleJWT::class)
->mutate(function(Mutators $mutators) {
// ...
});
}
}
See Mutating for more information on available mutators.
GuardAdapter
The GuardAdapter
interface allows you to have more control over how the token is parsed, validated, and the user is retrieved.
Create a class that implements the GuardAdapter
interface and implement the required methods:
use LittleApps\LittleJWT\Contracts\GuardAdapter;
use LittleApps\LittleJWT\JWT\JsonWebToken;
class MyAdapter implements GuardAdapter {
/**
* The options to use for the adapter.
*
* @var array
*/
protected $config;
/**
* Create a new adapter instance.
*
* @return void
*/
public function __construct(array $config)
{
$this->config = $config;
}
/**
* Parse a token from a string to a JWT.
* This does NOT check if the JWT is valid.
*
* @param string $token
* @return JsonWebToken JWT instance or null if unable to be parsed.
*/
public function parse(string $token)
{
// ...
}
/**
* Validate the JWT.
*
* @param JsonWebToken $jwt
* @return bool True if JWT is validated.
*/
public function validate(JsonWebToken $jwt)
{
// ...
}
/**
* Gets a user from the JWT
*
* @param UserProvider $provider
* @param JsonWebToken $jwt
* @return Authenticatable
*/
public function getUserFromJwt(UserProvider $provider, JsonWebToken $jwt)
{
// ...
}
}
Add an entry to the the config/littlejwt.php
file that has the class for the adapter and any other configuration options will be passed to the adapter class constructor when it's created:
return [
'guard' => [
'adapters' => [
'custom' => [
/**
* The fully qualified class name for the adapter.
*/
'adapter' => \Namespace\For\MyAdapter::class,
/**
* Add any additional configuration options below.
*/
],
],
],
];
Finally, set the guard adapter in the config/auth.php
file to your custom adapter name:
return [
'guards' => [
'jwt' => [
'adapter' => 'custom',
],
],
];
GuardAdapter
interface, use dependency injection with the constructor to automatically include any needed dependencies for the adapter.AbstractAdapter
class, a callback array can also be returned by the getValidatorCallback
method.Illuminate\Support\Facades\Auth
facade.BuildsJwt
trait can be used if the guard adapter builds JWTs for users. It currently only works with the AbstractAdapter
since it requires the $jwt
property.HasRequest
trait if the guard adapter will need anything from the request.