Laravel 8 JWT authentication tutorial
JSON Web Token(JWT) are an open standard RFC 7519 method for representing claims securely between two parties. JWT works on the builds public/private key pair. JWT is used to authenticate request between two parties.
JWT is a encoded string which contains three parts saperated with .
sign. The three parts are Header, Payload and Verify Signature. The format of the JWT is like s1ksDk8sd2.sdpcSd79a1.sda81eq
In this article, we will go through how to create authentication API using Jason Web Token. We will use tymondesigns/jwt-auth library to create authentication. We will go through step by step from the fresh application.
The tutorial contains below steps:
- Step 1: Create fresh Laravel application
- Step 2: Install and configure JWT library
- Step 3: Configuration of database in .env file
- Step 4: Update User model
- Step 5: Configure default authentication guard
- Step 6: Add Authentication routes
- Step 7: Create JWTController controller class
- Step 8: Test application in Postman
So let's start from creating latest Laravel application.
Step 1: Create fresh Laravel application
In the tutorial, the first step is to create new Laravel application. We will use following Composer command to create latest version of Laravel application. You can install Composer by following this article. Open the Terminal and run the following command.
composer create-project laravel/laravel jwt --prefer-dist
After the application is created, change Terminal working directory to project.
cd jwt
Step 2: Install and configure JWT library
In the second step, install JWT library using below Composer command.
composer require tymon/jwt-auth
Now register the library service provider to config/app.php
file. Open file and add the following lines into providers array.
'providers' => [
....
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
Publish JWT config file using vendor:command command into terminal.
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
This will copy configuration file from vendor to config/jwt.php
.
We also need to generate token secret. Run the below artisan command.
php artisan jwt:secret
This will create JWT token secret to .env file.
JWT_SECRET=RGffekr......hGKasf5u
Step 3: Configuration of database in .env file
Now we will need to configure database connection. Open .env file from the root directory and change below database credentials with your MySQL.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=jwt
DB_USERNAME=root
DB_PASSWORD=secret
We will use default users table to authenticate API. Laravel already have users table. You can customize users table field at database/migrations directory. Lastly migrate users table into database using following command.
php artisan migrate
Step 4: Update User model
Now we need to modify User model. Open App/Models/User.php
file and implement Tymon\JWTAuth\Contracts\JWTSubject
interface. We also need to add two model methods getJWTIdentifier()
and getJWTCustomClaims()
.
<?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;
/**
* 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 [];
}
}
Step 5: Configure default authentication guard
The default authentication guard is web. We need to change it to api. Open config/auth.php
file and change default guard to api.
<?php
return [
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
];
Step 6: Add Authentication routes
In this step, we need to register authentication routes into routes/api.php
file. Open the file and add below routes into it.
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\JWTController;
Route::group(['middleware' => 'api'], function($router) {
Route::post('/register', [JWTController::class, 'register']);
Route::post('/login', [JWTController::class, 'login']);
Route::post('/logout', [JWTController::class, 'logout']);
Route::post('/refresh', [JWTController::class, 'refresh']);
Route::post('/profile', [JWTController::class, 'profile']);
});
Step 7: Create JWTController controller class
We have defined routes for authentication so far. We need to create controller class to build application logic. The below Artisan command will generate controller class at App/Http/Controllers
directory.
php artisan make:controller JWTController
In the controller class, add the methods as per routes.
<?php
namespace App\Http\Controllers;
use Auth;
use Validator;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class JWTController extends Controller
{
/**
* Create a new AuthController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login', 'register']]);
}
/**
* Register user.
*
* @return \Illuminate\Http\JsonResponse
*/
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|string|min:2|max:100',
'email' => 'required|string|email|max:100|unique:users',
'password' => 'required|string|confirmed|min:6',
]);
if($validator->fails()) {
return response()->json($validator->errors(), 400);
}
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password)
]);
return response()->json([
'message' => 'User successfully registered',
'user' => $user
], 201);
}
/**
* login user
*
* @return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
if (!$token = auth()->attempt($validator->validated())) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
/**
* Logout user
*
* @return \Illuminate\Http\JsonResponse
*/
public function logout()
{
auth()->logout();
return response()->json(['message' => 'User successfully logged out.']);
}
/**
* Refresh token.
*
* @return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken(auth()->refresh());
}
/**
* Get user profile.
*
* @return \Illuminate\Http\JsonResponse
*/
public function profile()
{
return response()->json(auth()->user());
}
/**
* Get the token array structure.
*
* @param string $token
*
* @return \Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => auth()->factory()->getTTL() * 60
]);
}
}
We have created methods for authenticating APIs for Login, Register, Profile, Token Refresh and Logout routes.
Step 8: Test application in Postman
We have completed the application coding. Start the Laravel server using below Artisan command.
php artisan serve
For testing APIs, we will use Postman application. Postman is an API platform for building and using APIs. We will test all API. Lets start from register API.
Register API
All API routes are prefixed with api namespace. In the postman use http://localhost:8000/api/register
API endpoint. Pass name, email, password and password_confirmation parameters into request. You will get message and user details into response.
Login API
Use http://localhost:8000/api/login
API endpoint with email password parameter with request. If the email and password matches with registered user, you will receive token json object into response.
Profile API
All auth:api middleware routes are protected with api guard. You need to pass access_token in Header as bearer token.
Authorization: Bearer access_token
Refresh Token API
You can refresh the current token with new token using auth()->refresh() method.
Logout API
To logout the user, you need to invalidate the current token. You can simply call auth()->logout() method to invalidate current access token. Once user, logged out, it can't access protected routes.
Conclusion
Eventually, our tutorial is over. We have learned how to implement JWT authentication in Laravel application. In the next tutorial, we will use JWT token for REST API.
I hope, this tutorial will help on your development. If you liked this tutorial, please consider to share with your friends.
Copyright 2023 HackTheStuff