You already know about the data security of JSON. The RESTful API uses JSON data. While sending JSON data through the API, you have to take care of its access. You have to restrict unauthenticated access. You cannot reveal the data passing in the form of JSON to everyone. Hence, it is required to use an authentication token. The token will verify the authenticity of the user to access the API. There are several packages are available in Laravel for token-based API authentication. I already shared the REST API tutorial with Passport and Sanctum Auth. Today, I will share with you a post on JWT Authentication. Laravel JWT API authentication is much simpler than passport authentication.
Prerequisites
I am assuming, you already have the below tools for creating the Laravel 8 project. For API testing, I will be using Postman.
- PHP >= 7.3
- MySQL (version > 5)
- Apache/Nginx Server
- VS Code Editor
- Composer
- Postman/Insomnia
Now, let’s begin by creating a new project in Laravel 8.
Create Project in Laravel 8 For JWT Authentication
I will start with a fresh project setup for Laravel JWT API authentication. Here, I will be using composer to create a new project in Laravel 8. Therefore, you need to open the command prompt or terminal. Then enter the below command there.
composer create-project --prefer-dist laravel/laravel jwt-auth-api
It will take a couple of minutes to finish the installation.
After creating the project, let’s move to the database configuration. For the database, I am going to use MySQL.
How to Create Github Login in Laravel 8 Using Socialite
Configure Database For Laravel JWT API Authentication
I am going to create a new database in MySQL. Hence, you have to open the MySQL terminal and hit the below command.
CREATE DATABASE laravel_jwt;
I have created a database and it is ready to connect with our Laravel 8 project.
Now, move to the project folder and open it inside the editor. I am using VS code here. After opening the project, look at the .env file available at the root of the project. After that, add the DB credentials as showing below.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_jwt
DB_USERNAME=root
DB_PASSWORD=root
Here, you have configured the database with Laravel project successfully. Now, it’s time to install the JWT auth package inside our project.
How to Create Login with Twitter in Laravel 8 Using Socialite
Install JWT Package in Laravel 8
Open the terminal inside the project folder and search for the package. If you don’t know the exact package name then follow the below guideline.
composer require
When you will enter the above command, it will ask for the package name. So, I have entered jwt to get the exact package name. Then in the result, it has shown me the list of packages available related to JWT.
Now, choose the package or directly enter the below command.
composer require tymon/jwt-auth
The above command will install the jwt-auth package inside your project folder.
After installing the package, it will need to do some configuration.
Create LinkedIn Login in Laravel 8 Using Socialite
Add Provider and Alias of JWT Auth Package
In order to add provider and alias for the JWT package, navigate to the config/app.php file.
'providers' => [
...
...
...
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
'aliases' => [
...
...
...
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
After adding the providers stay ahead in the terminal. In the next step, we will publish the package configuration. Hence, hit the below command in the terminal.
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
The above command will publish the configuration of JWT inside the config folder.
Create Socialite Login with Google Account in Laravel 8
Generate a JWT Secret Key
After publishing the configuration, let’s create a secret key. So head up to terminal and hit the below command.
php artisan jwt:secret
This will generate the secret key inside the .env file
JWT_SECRET=SECRET_STRING_KEY
Now, let’s come to the functionalty implementation part of JWT token authentication.
Create Model and Migration
In Laravel, we have the default model for the User. Hence, we will be using that one for authentication purposes. Firstly, you will have to use a namespace before the class.
use Tymon\JWTAuth\Contracts\JWTSubject;
Next, you will have to implements the model class to above namespace.
class User extends Authenticatable implements JWTSubject {
}
Now, add the below functions inside the User class.
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims() {
return [];
}
After putting the above snippets the User model will look like this.
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier() {
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims() {
return [];
}
}
In the next step, need to migrate the tables. So, just enter the below command.
php artisan migrate
Next, you have to add the authentication guard for the HTTP requests.
How to Create Facebook Login in Laravel 8 Using Socialite
Add Auth Guard For JWT Authentication
For adding the JWT auth guard, look out at the config/auth.php file. Then inside the guards array just change the api driver to jwt.
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
],
Now, you can proceed for the jwt token authentication for the RESTful API.
Create Controller for JWT Token Authentication
For implementing the functionality of JWT token authentication just create a controller. So, in the terminal just hit the below command.
php artisan make:controller UserAuthController
After creating the controller, let’s add the below codes.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
use JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Illuminate\Support\Facades\Validator;
class UserAuthController extends Controller
{
/**
* Create an instace of UserAuthController
* @return void
*/
public function __construct() {
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
/**
* Register a User
* @return \Illuminate\Http\JsonResponse
*/
public function register(Request $request) {
$validator = Validator::make($request->all(), [
'name' => 'required|string|between:2,100',
'email' => 'required|string|email|max:100|unique:users',
'password' => 'required|string|confirmed|min:5',
]);
if($validator->fails()){
return response()->json($validator->errors(), 422);
}
$user = User::create(array_merge(
$validator->validated(),
['password' => bcrypt($request->password)]
));
return response()->json([
'message' => 'User registered successfully',
'user' => $user
], 201);
}
/**
* Get a JWT token after successful login
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request){
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|string|min:5',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
if (! $token = JWTAuth::attempt($validator->validated())) {
return response()->json(['status' => 'failed', 'message' => 'Invalid email and password.', 'error' => 'Unauthorized'], 401);
}
return $this->createNewToken($token);
}
/**
* Get the token array structure.
* @param string $token
* @return \Illuminate\Http\JsonResponse
*/
protected function createNewToken($token){
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth('api')->factory()->getTTL() * 60,
'user' => auth()->user()
]);
}
/**
* Refresh a JWT token
* @return \Illuminate\Http\JsonResponse
*/
public function refresh() {
return $this->createNewToken(auth()->refresh());
}
/**
* Get the Auth user using token.
* @return \Illuminate\Http\JsonResponse
*/
public function user() {
return response()->json(auth()->user());
}
/**
* Logout user (Invalidate the token).
* @return \Illuminate\Http\JsonResponse
*/
public function logout() {
auth()->logout();
return response()->json(['status' => 'success', 'message' => 'User logged out successfully']);
}
}
As per the controller, we need to add the routes respectively.
How to Schedule Tasks with Cron Job in Laravel 8
Add Routes
We are creating the RESTful API for JWT authentication, hence the routes will be added inside the routes/api.php file.
Route::group(['middleware' => 'api'], function ($router) {
Route::post('register', [UserAuthController::class, 'register']);
Route::post('login', [UserAuthController::class, 'login']);
Route::get('user', [UserAuthController::class, 'user']);
Route::post('refresh', [UserAuthController::class, 'refresh']);
Route::post('logout', [UserAuthController::class, 'logout']);
});
Now, you are good to go for the API testing. But, before testing the API, let me share the endpoints here.
Request Type | Endpoint | Parameters |
POST | api/register | Body->form-data (name, email, password, password_confirmation) |
POST | api/login | Body->form-data (email, password) |
GET | api/user | Authorization->Type = Bearer Token |
POST | api/refresh | Authorization->Type = Bearer Token |
POST | api/logout | Authorization->Type = Bearer Token |
Now, according to the above endpoints, let’s check the API in the postman.
How to Generate PDF File in Laravel 8 Using DOM PDF
Check the JWT Authentication API Result
User Registration API Result
I already specified the request type and parameters in the above table. So, at very first, I am checking without any parameters.
Now, let’s add the required fields in the form-data of the Body section.
After hitting the API, you will get the response as showing below.
Create Authentication in Laravel 8 Using Laravel Breeze
User Login API Result
After the registration, you can login through the email and password. The request type will be the same (POST). Firstly, check the validation. Hence, I have hit the API without giving any parameters.
Therefore, in the response, I have got the below result. Here, it is asking for the email and password.
Now, just give the required fields inside the form-data and re-hit the API endpoint.
In the response of the above endpoint, you will have the success of user login. Here, you will have the access_token that is generated by the JWT authentication. Also, you will have the current logged user data. Hence, you can use this data to store and manage the user session at the client-side.
We got the access_token here. Now, we will be using this auth token for getting current logged user detail and further more.
How to Configure PHPMailer in Laravel 8 For Sending Email
Auth User Detail API Result
For getting the auth user detail, you have to pass the access token inside the Authorization. In the Authorization, select the type to Bearer Token and paste the token in the Token value.
Now, hit the API and check the result as showing below. Here, we have the auth user detail in the response.
If you want to refresh the access token of the current auth user then you can do it. In order to do this, you will have to pass the existing token as a Bearer Token.
Dynamic Email Configuration in Laravel 8 For Sending Email
Refresh JWT Auth Token
The request type is POST and it will take the access token. Hence, put the token as showing below and hit the API.
In the response, you will have the new access token for that user. Now, you can use the new token for hitting API respectively.
At last, we have the user logout end point. So, let’s check that one also.
How to Upload Image in CKEditor 5 Using Laravel 8
User Logout API Result
For revoking the access token you have to log out with the auth token. Hence, the request type will be POST and this end point will take the auth token in the authorization.
So, after passing the Authorization Bearer Token, just hit the API.
In the response, you will get the success as showing below. Here, the user has been logged out successfully.
How to Create and Use Database Seeder in Laravel 8
Conclusion
In this post, we learned the implementation of JWT for REST API. The Laravel JWT API authentication is managed for the accessing of resources, routes, services. The access token has a certain time. We have seen the token expiry time. You can increase or set it as per your requirement. But, it is more secure if you validate it for a short time. After the token expired, you will require to generate a new token. You can refresh the token for the auth user. Similarly, for accessing the routes inside the middleware of auth:api, you will need the access token in the authorization as a bearer. The Bearer Token will validate the request type on the basis of given token. So, that’s it for the Laravel JWT token-based API tutorial. Try to implement it and let me know of any kind of issue if you get. Thank you.
Leave a Reply