JWT authentication guard and tools for your Laravel REST APIs
Laravel JWT guard and authentication tools
This package is no longer maintained.
You can use the laravel/passport package instead.
Or you may use miladrahimi/php-jwt to create your custom jwt guard.
LaraJwt is a Laravel package for generating JWT (JSON Web-based Token) from users and providing JWT guard for Laravel
applications.
Add the package via Composer:
composer require miladrahimi/larajwt:2.*
Then run the following command to generate jwt.php
(the package config) in your Laravel config directory:
php artisan vendor:publish --tag=larajwt-config
The package service provider will be automatically discovered by Laravel package discovery.
The JwtAuth
alias for MiladRahimi\LaraJwt\Facades\JwtAuth
will be automatically registered.
To configure the package open jwt.php
file in your laravel config directory. This files consists of following items:
key
: The secret key to sign the token, it uses your project key if you leave it empty.ttl
: Time that token will be valid, token will be expired after this time (in seconds)issuer
: Issuer claimaudience
: Audience claimmodel_safe
: Set it true if you have different authentication for different models with LaraJwt, it ensures thatUse the method below to generate JWT from users or any other authenticable entities (models):
$jwt = JwtAuth::generateToken($user);
For example you may generate JWT from users in the sign-in process like this:
$credential = [
'email' => $request->input('email'),
'password' => $request->input('password'),
];
if(Auth::guard('api')->attempt($credential)) {
$user = Auth::guard('api')->user();
$jwt = JwtAuth::generateToken($user);
// Return successfull sign in response with the generated jwt.
} else {
// Return response for failed attempt...
}
If you want to store more information like role in the token, you can pass them to the method this way:
$customClaims = ['role' => 'admin', 'foo' => 'bar'];
$jwt = JwtAuth::generateToken($user, $customClaims);
Add as many as guard you need in your config/auth.php
with jwt
driver like this example:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
After configuring guards in config/auth.php
you can protect routes by the defined guards.
In our example we can protect route like this:
Route::group(['middleware' => 'auth:api'], function () {
// Routes...
});
Authorization: Bearer <jwt>
in their requests.To retrieve current user and his info in your application (controllers for example) you can do it this way:
// To get current user
$user = Auth::guard('api')->user();
$user = Auth::guard('api')->getUser();
// To get current user id
$user = Auth::guard('api')->id();
// Is current user guest
$user = Auth::guard('api')->guest();
// To get current token
$jwt = Auth::guard('api')->getToken();
// To get current token claims
$claims = Auth::guard('api')->getClaims();
// To get a sepcific claim from current token
$role = Auth::guard('api')->getClaim('role');
// Logout current user (JWT will be cached in blacklist and NOT valid in next requests).
Auth::guard('api')->logout();
// Logout current user (but it will be VALID next reuqests).
// It clears caches so user will be fetched and filters will be executed again in next request.
Auth::guard('api')->logout(false);
Since LaraJwt caches user fetching it can authenticate users without touching database.
You may need to retrieve user from generated JWTs manually, no worry! just do it this way:
$user = JwtAuth::retrieveUser($jwt);
It uses default user provider to fetch the user,
if you are using different provider you can pass it to the method as the second parameter like this:
$admin = JwtAuth::retrieveUser($jwt, 'admin');
You my even go further and need to retrieve JWT claims manually, it has considered too.
$claims = JwtAuth::retrieveClaims($jwt);
The mentioned method returns associative array of claims with following structure:
[
'sub' => '666',
'iss' => 'Your app name',
'aud' => 'Your app audience',
// ...
]
LaraJwt caches retrieving users process , so after first successful authentication it remembers jwt as long as ttl
which is set in config, you may clear this cache to force LaraJwt to re-run filters or re-fetch user model from
database, to do so you can use the this method:
JwtAuth::clearCache($user);
You can pass user model (Authenticable) or its primary key to the clearCache
method.
Filters are runnable closures which will be called after parsing token and fetching user model.
For example if you have considered boolean property like is_active
for users,
you probably want to check its value after authentication and raise some exception if it is false or change LaraJwt
normal process the way it be seemed authentication is failed.
You can register filters as many as you need, LaraJwt runs them one by one after authentication.
AuthServiceProvider seems a good place to register hooks.
class AuthServiceProvider extends ServiceProvider
{
// ...
public function boot()
{
// ...
$jwtAuth = $this->app->make(JwtAuthInterface::class);
// Check if user is active or not
$jwtAuth->registerFilter(function (User $user) {
if ($user->is_active == true) {
return $user;
} else {
return null;
}
});
}
}
The registerFilter
takes a closure with one argument to get authenticated user and it should return the user if there
is no problem, it can return null if you want make the authentication failed.
As mentioned with example above you can logout user with following method:
Auth::guard('api')->logout();
It takes one boolean parameter that is true in default and put the jwt in cached blacklist so the token won’t be valid
in next requests, but you can pass false to make it only logout current user and clear cache.
You can also invalidate tokens with JwtAuth
facade and jti
claim this way:
JwtAuth::invalidate($jti);
Exception Class: LaraJwtConfiguringException
Exception Message: LaraJwt config not found.
This exception would be thrown if you had not published the package config (mentioned in Installation section).
You may consider simple database-stored tokens as the alternative for JWT for authenticating,
So we have provided some differences and comparison for you.
Any contribution will be appreciated :D
This package is released under the MIT License.