Laravel 12 API Authentication with Sanctum

Laravel 12 API Authentication with Sanctum

 Guide to building a secure Laravel 12 REST API using Laravel Sanctum for token-based authentication. Laravel Sanctum is a simple package for API token authentication and is ideal for SPAs or mobile apps.

Laravel 12 API Authentication with Sanctum

Prerequisites

Before starting, ensure you have:

  • PHP 8.1+

  • Composer

  • Laravel 12

  • MySQL or MariaDB

  • Postman (for testing)

Step 1: Create a Laravel 12 Project

composer create-project laravel/laravel laravel-sanctum-api

Step 2: Install Laravel Sanctum

composer require laravel/sanctum

Step 3: Add HasApiTokens to User Model

In app/Models/User.php, add:

use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable; }

Step 4: Configure Database

In your .env file:

DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=your_db_name DB_USERNAME=your_db_user DB_PASSWORD=your_db_password

Then run:

php artisan migrate

Step 5: Create API Routes

If the a install:api A command is available; run it in your terminal:

php artisan install:api

This will automatically generate API controllers, routes, and configurations, and may also install any

Step 6: Define API Routes

Open routes/api.php and add:

Route::group(['namespace' => 'App\Http\Controllers\API'], function () { // --------------- Register and Login ----------------// Route::post('register', 'AuthenticationController@register')->name('register'); Route::post('login', 'AuthenticationController@login')->name('login'); // ------------------ Get Data ----------------------// Route::middleware('auth:sanctum')->group(function () { Route::get('get-user', 'AuthenticationController@userInfo')->name('get-user'); Route::post('logout', 'AuthenticationController@logOut')->name('logout'); }); });

Step 7: Create Authentication Controller

php artisan make:controller API/AuthenticationController

Step 8: AuthenticationController Logic

Edit app/Http/Controllers/API/AuthenticationController.php:

<?php namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Log; use Illuminate\Validation\ValidationException; use App\Models\User; class AuthenticationController extends Controller { /** * Register a new account. */ public function register(Request $request) { try { $validated = $request->validate([ 'name' => 'required|string|min:4', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8', ]); $user = User::create([ 'name' => $validated['name'], 'email' => $validated['email'], 'password' => Hash::make($validated['password']), ]); return response()->json([ 'response_code' => 201, 'status' => 'success', 'message' => 'Successfully registered', ], 201); } catch (ValidationException $e) { return response()->json([ 'response_code' => 422, 'status' => 'error', 'message' => 'Validation failed', 'errors' => $e->errors(), ], 422); } catch (\Exception $e) { Log::error('Registration Error: ' . $e->getMessage()); return response()->json([ 'response_code' => 500, 'status' => 'error', 'message' => 'Registration failed', ], 500); } } /** * Login and return auth token. */ public function login(Request $request) { try { $credentials = $request->validate([ 'email' => 'required|email', 'password' => 'required|string', ]); if (!Auth::attempt($credentials)) { return response()->json([ 'response_code' => 401, 'status' => 'error', 'message' => 'Unauthorized', ], 401); } $user = Auth::user(); $token = $user->createToken('authToken')->plainTextToken; return response()->json([ 'response_code' => 200, 'status' => 'success', 'message' => 'Login successful', 'user_info' => [ 'id' => $user->id, 'name' => $user->name, 'email' => $user->email, ], 'token' => $token, 'token_type' => 'Bearer', ]); } catch (ValidationException $e) { return response()->json([ 'response_code' => 422, 'status' => 'error', 'message' => 'Validation failed', 'errors' => $e->errors(), ], 422); } catch (\Exception $e) { Log::error('Login Error: ' . $e->getMessage()); return response()->json([ 'response_code' => 500, 'status' => 'error', 'message' => 'Login failed', ], 500); } } /** * Get list of users (paginated) — protected route. */ public function userInfo() { try { $users = User::latest()->paginate(10); return response()->json([ 'response_code' => 200, 'status' => 'success', 'message' => 'Fetched user list successfully', 'data_user_list' => $users, ]); } catch (\Exception $e) { Log::error('User List Error: ' . $e->getMessage()); return response()->json([ 'response_code' => 500, 'status' => 'error', 'message' => 'Failed to fetch user list', ], 500); } } /** * Logout user and revoke tokens — protected route. */ public function logOut(Request $request) { try { $user = $request->user(); if ($user) { $user->tokens()->delete(); return response()->json([ 'response_code' => 200, 'status' => 'success', 'message' => 'Successfully logged out', ]); } return response()->json([ 'response_code' => 401, 'status' => 'error', 'message' => 'User not authenticated', ], 401); } catch (\Exception $e) { Log::error('Logout Error: ' . $e->getMessage()); return response()->json([ 'response_code' => 500, 'status' => 'error', 'message' => 'An error occurred during logout', ], 500); } } }

Step 9: Run the Server

php artisan serve 

Step 10: Test Routes in Postman

ActionMethodURLAuth Header
RegisterPOSThttp://localhost:8000/api/register-
LoginPOSThttp://localhost:8000/api/login-
Get UserGEThttp://localhost:8000/api/get-userBearer your_token
LogoutPOSThttp://localhost:8000/api/logoutBearer your_token

Step 1: Test API with Postman

Register

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

  • Body (JSON):

{ "name": "StarCode Kh", "email": "starcodekh@example.com", "password": "password@123" }

Login

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

  • Response will include the token.

Get Authenticated User

  • GET http://127.0.0.1:8000/api/get-user

  • Header:

Authorization: Bearer YOUR_TOKEN_HERE

Logout

  • POST http://127.0.0.1:8000/api/logout

  • Header:

Authorization: Bearer YOUR_TOKEN_HERE

Conclusion

You’ve now built a secure Laravel 12 REST API with:

  • User registration

  • Login with token generation

  • Protected routes using auth:sanctum

  • Token-based logout

Souy Soeng

Souy Soeng

Our website teaches and reads PHP, Framework Laravel, and how to download Admin template sample source code free. Thank you for being so supportive!

Github

Post a Comment

CAN FEEDBACK
close