Updated 19 June 2026
Laravel API authentication using JWT is a secure way to protect modern web applications and APIs.
Authentication is essential in modern web apps to protect user data and APIs.
Traditional session-based authentication can be limiting for stateless systems like APIs and SPAs.
JWT (JSON Web Token) offers a secure, scalable, stateless way to authenticate users without server-side sessions.
In this guide, you’ll learn how Laravel API authentication using JWT works, explore its advantages,
and implement it step by step to build secure and efficient REST APIs.
JSON Web Token (JWT) is an open standard (RFC 7519) used for securely transmitting information between parties as a JSON object.
A JWT consists of three parts:
|
1 |
Header.Payload.Signature |
Example:
|
1 2 3 4 5 |
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJzdWIiOiIxMjM0NTY3ODkwIn0 . dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U |
Contains token metadata and signing algorithm.
|
1 2 3 4 |
{ "alg": "HS256", "typ": "JWT" } |
Contains claims and user-related information.
|
1 2 3 4 |
Used to verify the integrity of the token.
JWT offers several advantages:
No need to store session data on the server.
Ideal for distributed systems and microservices.
Works seamlessly with Android and iOS applications.
Perfect for APIs consumed by multiple frontend applications.
Reduces database lookups and session management overhead.
Laravel does not include JWT support by default, so install the popular package:
|
1 |
composer require tymon/jwt-auth |
Generate the package configuration file:
|
1 |
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider" |
This creates:
|
1 |
config/jwt.php |
Generate a secret key used to sign tokens:
|
1 |
php artisan jwt:secret |
A new entry will be added to your .env file:
|
1 |
JWT_SECRET=your_generated_secret_key |
Keep this key secure and never expose it publicly.
Update the User model to implement the JWTSubject interface.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php namespace App\Models; use Tymon\JWTAuth\Contracts\JWTSubject; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable implements JWTSubject { public function getJWTIdentifier() { return $this->getKey(); } public function getJWTCustomClaims() { return []; } } |
Update config/auth.php.
|
1 2 3 4 5 6 |
'guards' => [ 'api' => [ 'driver' => 'jwt', 'provider' => 'users', ], ], |
This tells Laravel to use JWT for API authentication.
Create an authentication controller:
|
1 |
php artisan make:controller AuthController |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public function register(Request $request) { $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|min:8|confirmed' ]); $user = User::create([ 'name' => $validated['name'], 'email' => $validated['email'], 'password' => bcrypt($validated['password']) ]); return response()->json([ 'message' => 'User registered successfully' ]); } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public function login(Request $request) { $credentials = $request->only('email', 'password'); if (!$token = auth('api')->attempt($credentials)) { return response()->json([ 'message' => 'Invalid credentials' ], 401); } return response()->json([ 'access_token' => $token, 'token_type' => 'Bearer', 'expires_in' => auth('api')->factory()->getTTL() * 60 ]); } |
|
1 2 3 4 |
public function me() { return response()->json(auth('api')->user()); } |
|
1 2 3 4 5 6 |
public function refresh() { return response()->json([ 'access_token' => auth('api')->refresh() ]); } |
|
1 2 3 4 5 6 7 8 |
public function logout() { auth('api')->logout(); return response()->json([ 'message' => 'Successfully logged out' ]); } |
Add routes in routes/api.php.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
use App\Http\Controllers\AuthController; Route::prefix('auth')->group(function () { Route::post('/register', [AuthController::class, 'register']); Route::post('/login', [AuthController::class, 'login']); Route::middleware('auth:api')->group(function () { Route::get('/me', [AuthController::class, 'me']); Route::post('/refresh', [AuthController::class, 'refresh']); Route::post('/logout', [AuthController::class, 'logout']); }); }); |
Any route can be protected using Laravel middleware.
|
1 2 3 4 5 6 7 |
Route::middleware('auth:api')->group(function () { Route::get('/profile', function () { return auth()->user(); }); }); |
Requests without a valid JWT token will receive a 401 Unauthorized response.
After login, store the token securely.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const response = await fetch('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ password: 'password' }) }); const data = await response.json(); localStorage.setItem('token', data.access_token); |
|
1 2 3 4 5 |
fetch('/api/auth/me', { headers: { Authorization: `Bearer ${localStorage.getItem('token')}` } }); |
JWT tokens should never be transmitted over unsecured HTTP connections.
Configure token lifetime in:
|
1 |
config/jwt.php |
Example:
|
1 |
'ttl' => 60 |
This expires tokens after 60 minutes.
Short-lived access tokens combined with refresh tokens improve security significantly.
Never store passwords, personal information, or confidential business data inside JWT payloads.
You can include user roles directly inside JWT claims.
|
1 2 3 4 5 6 |
public function getJWTCustomClaims() { return [ 'role' => $this->role ]; } |
This helps build authorization systems efficiently.
Error
|
1 |
TokenExpiredException |
Solution
Use the refresh endpoint to generate a new access token.
Error
|
1 |
Token not provided |
Solution
Ensure the request contains:
|
1 |
Authorization: Bearer YOUR_TOKEN |
Error
|
1 |
Unauthorized |
Solution
Verify the email and password before generating the token.
Example Laravel feature test:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
public function test_user_can_login() { $user = User::factory()->create([ 'password' => bcrypt('password123') ]); $response = $this->postJson('/api/auth/login', [ 'email' => $user->email, 'password' => 'password123' ]); $response->assertStatus(200); } |
Testing ensures authentication continues to work correctly as your application evolves.
If you’re building a Laravel REST API, mastering JWT authentication is an essential skill that will help you create secure, production-ready applications.
Also you can hire laravel developers to customize this feature for your business needs.
Kindly explore our extensions.
If you have more details or questions, you can reply to the received confirmation email.
Back to Home
Be the first to comment.