Laravel 12 with JWT Authentication: A Beginner-Friendly Guide

Author

Kritim Yantra

Mar 28, 2025

Laravel 12 with JWT Authentication: A Beginner-Friendly Guide

If you're building a web or mobile app, you’ll need a secure way to authenticate users. JSON Web Tokens (JWT) are a popular solution because they allow stateless, token-based authentication.

In this guide, we’ll learn how to:
Set up JWT in Laravel 12
Create login & registration APIs
Protect routes with JWT
Test the API using Postman

By the end, you'll have a fully working JWT authentication system in Laravel!


🔹 What is JWT?

JWT (JSON Web Token) is a secure way to transmit data between a client (like a React app) and a server (Laravel).

How JWT Works

  1. User logs in → Server generates a token.
  2. Token is stored (e.g., in browser localStorage).
  3. Every API request includes this token for authentication.
  4. Server verifies the token before allowing access.

🔐 Why use JWT?
✅ No need for sessions (stateless)
✅ Works well with mobile apps & SPAs
✅ Secure (signed with a secret key)


🔹 Step 1: Setting Up Laravel 12

1. Install Laravel

composer create-project laravel/laravel laravel-jwt
cd laravel-jwt

2. Install API

php artisan install:api

3. Install JWT Package

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

composer require tymon/jwt-auth

4. Publish JWT Config

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

5. Generate JWT Secret Key

php artisan jwt:secret

This adds a JWT_SECRET key in .env.


🔹 Step 2: Configure Laravel for JWT

1. Update config/auth.php

Change the default guard to api with JWT driver:

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

2. Modify the User Model

Update app/Models/User.php to implement JWTSubject:

use Tymon\JWTAuth\Contracts\JWTSubject;

class User extends Authenticatable implements JWTSubject
{
    // ...

    public function getJWTIdentifier()
    {
        return $this->getKey(); // Returns user ID
    }

    public function getJWTCustomClaims()
    {
        return []; // Extra data in token (optional)
    }
}

🔹 Step 3: Create Auth APIs

1. Make Auth Controller

php artisan make:controller AuthController

2. Add Login & Register Logic

Update app/Http/Controllers/AuthController.php:

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $request->validate([
            'name' => 'required|string',
            'email' => 'required|email|unique:users',
            'password' => 'required|min:6',
        ]);

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

        $token = Auth::login($user);

        return response()->json([
            'status' => 'success',
            'token' => $token,
            'user' => $user,
        ]);
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required',
        ]);

        $credentials = $request->only('email', 'password');

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

        return response()->json([
            'status' => 'success',
            'token' => $token,
            'user' => Auth::user(),
        ]);
    }

    public function user()
    {
        return response()->json(Auth::user());
    }
}

3. Define API Routes

In routes/api.php:

use App\Http\Controllers\AuthController;

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

🔹 Step 4: Testing with Postman

1. Register a User

  • Method: POST
  • URL: http://localhost:8000/api/register
  • Body (JSON):
{
    "name": "John Doe",
    "email": "john@example.com",
    "password": "password123"
}

Response:

{
    "status": "success",
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "user": { "id": 1, "name": "John Doe", "email": "john@example.com" }
}

2. Login

  • Method: POST
  • URL: http://localhost:8000/api/login
  • Body (JSON):
{
    "email": "john@example.com",
    "password": "password123"
}

Response: Same as register (with a new token).

3. Get User Data (Protected Route)

  • Method: GET
  • URL: http://localhost:8000/api/user
  • Headers:
    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
    

Response:

{ "id": 1, "name": "John Doe", "email": "john@example.com" }

🔹 Common Issues & Fixes

1. "Token not provided" error

Solution: Ensure the Authorization header is correctly formatted:

Authorization: Bearer your_token_here

2. "Token expired" error

Solution:

  • Increase token lifetime in .env:
    JWT_TTL=1440 # (in minutes)
    
  • Or implement token refreshing (advanced).

3. CORS Errors

Solution: Install fruitcake/laravel-cors:

composer require fruitcake/laravel-cors

Then enable it in config/cors.php.


🔹 Conclusion

🎉 You’ve successfully set up JWT in Laravel 12!

What We Covered:

✔ Installed & configured JWT
✔ Created register/login APIs
✔ Protected routes with JWT middleware
✔ Tested with Postman

Happy coding! 😊🚀

Tags

Laravel Php

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Continue with Google

Related Posts