Secure Your Laravel App with JWT Authentication

Learn how to implement JWT authentication in Laravel step by step. A beginner-friendly guide with code examples and best practices. Introduction Authentication is a crucial part of web applications, ensuring that only authorized users can access protected resources. One of the most popular ways to handle authentication in modern applications is by using JSON Web Tokens (JWT). In this guide, we’ll walk you through how to implement JWT authentication in Laravel. Whether you're a complete beginner or just looking for an easy-to-follow tutorial, this guide is for you! What is JWT and Why Use It? JSON Web Token (JWT) is a secure and compact way to transmit authentication data between a client and a server. Here’s why it’s widely used: ✅ Stateless Authentication – No need to store sessions on the server. ✅ Secure – Uses encryption to protect sensitive user information. ✅ Cross-platform – Works with mobile apps, SPAs, and APIs. When a user logs in, the server generates a JWT token, which is then stored in the client (e.g., local storage or HTTP headers). On subsequent requests, the token is sent to verify the user's identity. Step 1: Set Up a New Laravel Project First, make sure you have Laravel installed. If not, install it using Composer: composer create-project --prefer-dist laravel/laravel jwt-auth-app Navigate to your project directory: cd jwt-auth-app Step 2: Install Laravel JWT Package We’ll use tymon/jwt-auth, a popular package for handling JWT authentication in Laravel. Run the following command: composer require tymon/jwt-auth Now, publish the package configuration: php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider" Generate the JWT secret key: php artisan jwt:secret This key is stored in your .env file under JWT_SECRET. Step 3: Configure Authentication Guards Open the config/auth.php file and update the guards array: 'guards' => [ 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], ], This tells Laravel to use JWT for API authentication. Step 4: Set Up User Model for JWT Modify the User.php model to implement JWTSubject: use Tymon\JWTAuth\Contracts\JWTSubject; class User extends Authenticatable implements JWTSubject { use Notifiable; public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return []; } } Step 5: Create Authentication Controller Now, let’s create an authentication controller to handle login, register, and logout. Run: php artisan make:controller AuthController Inside AuthController.php, add the following methods: User Registration public function register(Request $request) { $validatedData = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]); $user = User::create([ 'name' => $validatedData['name'], 'email' => $validatedData['email'], 'password' => bcrypt($validatedData['password']), ]); $token = auth()->login($user); return response()->json(['token' => $token]); } User Login public function login(Request $request) { $credentials = $request->only('email', 'password'); if (!$token = auth()->attempt($credentials)) { return response()->json(['error' => 'Unauthorized'], 401); } return response()->json(['token' => $token]); } User Logout public function logout() { auth()->logout(); return response()->json(['message' => 'Successfully logged out']); } Step 6: Set Up Routes Open routes/api.php and add the following routes: Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']); Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:api'); Step 7: Protect Routes with JWT Middleware To secure API routes, apply the auth:api middleware: Route::middleware('auth:api')->group(function () { Route::get('/profile', function () { return response()->json(auth()->user()); }); }); Now, only authenticated users can access /profile. Step 8: Testing JWT Authentication Test Registration Send a POST request to: POST http://127.0.0.1:8000/api/register With this JSON payload: { "name": "John Doe", "email": "johndoe@example.com", "password": "password123", "password_confirmation": "password123" } Test Login POST http://127.0.0.1:8000/api/login Payload: { "email": "johndoe@example.com", "password": "password123" } It returns a JWT token: { "token": "your-jwt-token

Mar 20, 2025 - 13:52
 0
Secure Your Laravel App with JWT Authentication

Learn how to implement JWT authentication in Laravel step by step. A beginner-friendly guide with code examples and best practices.

Introduction

Authentication is a crucial part of web applications, ensuring that only authorized users can access protected resources. One of the most popular ways to handle authentication in modern applications is by using JSON Web Tokens (JWT).

In this guide, we’ll walk you through how to implement JWT authentication in Laravel. Whether you're a complete beginner or just looking for an easy-to-follow tutorial, this guide is for you!

What is JWT and Why Use It?

JSON Web Token (JWT) is a secure and compact way to transmit authentication data between a client and a server. Here’s why it’s widely used:

Stateless Authentication – No need to store sessions on the server.

Secure – Uses encryption to protect sensitive user information.

Cross-platform – Works with mobile apps, SPAs, and APIs.

When a user logs in, the server generates a JWT token, which is then stored in the client (e.g., local storage or HTTP headers). On subsequent requests, the token is sent to verify the user's identity.

Step 1: Set Up a New Laravel Project

First, make sure you have Laravel installed. If not, install it using Composer:

composer create-project --prefer-dist laravel/laravel jwt-auth-app

Navigate to your project directory:

cd jwt-auth-app

Step 2: Install Laravel JWT Package

We’ll use tymon/jwt-auth, a popular package for handling JWT authentication in Laravel.

Run the following command:

composer require tymon/jwt-auth

Now, publish the package configuration:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

Generate the JWT secret key:

php artisan jwt:secret

This key is stored in your .env file under JWT_SECRET.

Step 3: Configure Authentication Guards

Open the config/auth.php file and update the guards array:

'guards' => [
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

This tells Laravel to use JWT for API authentication.

Step 4: Set Up User Model for JWT

Modify the User.php model to implement JWTSubject:

use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }
}

Step 5: Create Authentication Controller

Now, let’s create an authentication controller to handle login, register, and logout.

Run:

php artisan make:controller AuthController

Inside AuthController.php, add the following methods:

User Registration

public function register(Request $request)
{
    $validatedData = $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users',
        'password' => 'required|string|min:6|confirmed',
    ]);

    $user = User::create([
        'name' => $validatedData['name'],
        'email' => $validatedData['email'],
        'password' => bcrypt($validatedData['password']),
    ]);

    $token = auth()->login($user);

    return response()->json(['token' => $token]);
}

User Login

public function login(Request $request)
{
    $credentials = $request->only('email', 'password');

    if (!$token = auth()->attempt($credentials)) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }

    return response()->json(['token' => $token]);
}

User Logout

public function logout()
{
    auth()->logout();
    return response()->json(['message' => 'Successfully logged out']);
}

Step 6: Set Up Routes

Open routes/api.php and add the following routes:

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout'])->middleware('auth:api');

Step 7: Protect Routes with JWT Middleware

To secure API routes, apply the auth:api middleware:

Route::middleware('auth:api')->group(function () {
    Route::get('/profile', function () {
        return response()->json(auth()->user());
    });
});

Now, only authenticated users can access /profile.

Step 8: Testing JWT Authentication

Test Registration

Send a POST request to:

POST http://127.0.0.1:8000/api/register

With this JSON payload:

{
    "name": "John Doe",
    "email": "johndoe@example.com",
    "password": "password123",
    "password_confirmation": "password123"
}

Test Login

POST http://127.0.0.1:8000/api/login

Payload:

{
    "email": "johndoe@example.com",
    "password": "password123"
}

It returns a JWT token:

{
    "token": "your-jwt-token-here"
}

Test Accessing a Protected Route

Use the token to access /profile:

GET http://127.0.0.1:8000/api/profile

Set the Authorization header:

Authorization: Bearer your-jwt-token-here

If successful, it returns the authenticated user’s details.

Conclusion

Congratulations!