Laravel 12 API Authentication with Passport and Post CRUD

Laravel 12 API Authentication with Passport and Post CRUD

Laravel 12 API Authentication with Passport + Post CRUD

Tutorial for building a Laravel 12 RESTful API with Passport authentication and CRUD functionality for a Post model. This guide is ideal for APIs that will be consumed by SPAs, mobile apps, or third-party clients using OAuth2 tokens.

Prerequisites

Make sure the following are installed:

  • PHP 8.1+

  • Composer

  • Laravel 12

  • MySQL or MariaDB

  • Postman (for API testing)

Step 1: Create a New Laravel Project

composer create-project laravel/laravel laravel-passport-api

Step 2: Configure Database

Update .env:

DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=passport_api DB_USERNAME=root DB_PASSWORD=

Step 3: Install Laravel Passport

composer require laravel/passport

Install Passport:

php artisan passport:install

Step 4: Configure Passport

config/auth.php

Change the API guard driver to passport:

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

Step 5: Update User Model

In app/Models/User.php:

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

Run this command in your terminal:

php artisan install:api

This command (if supported in your Laravel version) will automatically:

  • Create API route files (in routes/api.php)

Step 6: Define API Routes

In Update routes/api.php:

use App\Http\Controllers\PostController;
use App\Http\Controllers\API\AuthenticationController; Route::post('register', [AuthenticationController::class, 'register']); Route::post('login', [AuthenticationController::class, 'login']); Route::middleware('auth:api')->group(function () { Route::get('user', [AuthenticationController::class, 'userInfo']); Route::post('logout', [AuthenticationController::class, 'logOut']); Route::apiResource('posts', PostController::class); });

Step 7: Create Authentication Controller

php artisan make:controller API/AuthenticationController

In app/Http/Controllers/API/AuthenticationController.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 App\Models\User; class AuthenticationController extends Controller { public function register(Request $request) { $request->validate([ 'name' => 'required|string|min:3', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6', ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); return response()->json(['message' => 'User registered successfully']); } public function login(Request $request) { $request->validate([ 'email' => 'required|email', 'password' => 'required|string', ]); if (!Auth::attempt($request->only('email', 'password'))) { return response()->json(['message' => 'Invalid credentials'], 401); } $user = Auth::user(); $token = $user->createToken('Personal Access Token')->accessToken; return response()->json(['token' => $token]); } public function userInfo(Request $request) { return response()->json($request->user()); } public function logOut(Request $request) { $request->user()->token()->revoke(); return response()->json(['message' => 'Logged out successfully']); } }

Step 8: Create Post Model, Migration, and Controller

php artisan make:model Post -mcr

Update migration in database/migrations/xxxx_create_posts_table.php:

public function up(): void { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->foreignId('user_id')->constrained()->onDelete('cascade'); $table->string('title'); $table->text('body'); $table->timestamps(); }); }

Run migration:

php artisan migrate

Step 9: PostController Logic

In app/Http/Controllers/PostController.php:

namespace App\Http\Controllers; use App\Models\Post; use Illuminate\Http\Request; class PostController extends Controller { public function index() { return response()->json(Post::with('user')->latest()->get()); } public function store(Request $request) { $request->validate([ 'title' => 'required|string|max:255', 'body' => 'required|string', ]); $post = $request->user()->posts()->create($request->only('title', 'body')); return response()->json(['message' => 'Post created', 'post' => $post]); } public function show(Post $post) { return response()->json($post); } public function update(Request $request, Post $post) { $request->validate([ 'title' => 'required|string|max:255', 'body' => 'required|string', ]); $post->update($request->only('title', 'body')); return response()->json(['message' => 'Post updated', 'post' => $post]); } public function destroy(Post $post) { $post->delete(); return response()->json(['message' => 'Post deleted']); } }

Step 10: Define Relationships

app/Models/User.php

public function posts() { return $this->hasMany(\App\Models\Post::class); }

app/Models/Post.php

protected $fillable = ['title', 'body', 'user_id']; public function user() { return $this->belongsTo(\App\Models\User::class); } 

Step 11: Personal

To create a personal access client in Laravel, you can use the following Artisan command:

php artisan passport:client --personal

Step 12: Start Server

php artisan serve
This will make your application accessible at http://localhost:8000 by default.

Step 13: API Testing in Postman

Auth Endpoints

ActionMethodURLAuth Header
RegisterPOSThttp://localhost:8000/api/register
LoginPOSThttp://localhost:8000/api/login
Get User InfoGEThttp://localhost:8000/api/userBearer YOUR_TOKEN
LogoutPOSThttp://localhost:8000/api/logoutBearer YOUR_TOKEN

Example Request (Register)

POST /api/register Content-Type: application/json { "name": "StarCode KH", "email": "starcodekh@example.com", "password": "password123" }

Example Request (Login)

POST /api/login Content-Type: application/json { "email": "starcodekh@example.com", "password": "password123" }

After login, you'll get a response like:

{ "token": "eyJ0eXAiOiJKV1QiLCJhbGciOi..." }

Use that token in the Authorization tab in Postman:

  • Type: Bearer Token

  • Token: paste_your_token_here

Post CRUD Endpoints

ActionMethodURLAuth Header
Get AllGEThttp://localhost:8000/api/postsBearer YOUR_TOKEN
CreatePOSThttp://localhost:8000/api/postsBearer YOUR_TOKEN
View OneGEThttp://localhost:8000/api/posts/{id}Bearer YOUR_TOKEN
UpdatePUThttp://localhost:8000/api/posts/{id}Bearer YOUR_TOKEN
DeleteDELETEhttp://localhost:8000/api/posts/{id}Bearer YOUR_TOKEN

Example Create Post Request

POST /api/posts Content-Type: application/json Authorization: Bearer YOUR_TOKEN { "title": "My First Post", "body": "This is the content of my first post." }

Example Update Post Request

PUT /api/posts/{id} Content-Type: application/json Authorization: Bearer YOUR_TOKEN

{ "title": "My Updated Post", "body": "This is the updated content of my post." }

Summary

You now have a fully functional Laravel 12 API with:

  • ✅ User Registration & Login

  • ✅ Passport Token Authentication

  • ✅ Protected API Endpoints

  • ✅ Full CRUD for Posts

  • ✅ Ready for Postman/API Client

Souy Soeng

Souy Soeng

Hi there 👋, I’m Soeng Souy (StarCode Kh)
-------------------------------------------
🌱 I’m currently creating a sample Laravel and React Vue Livewire
👯 I’m looking to collaborate on open-source PHP & JavaScript projects
💬 Ask me about Laravel, MySQL, or Flutter
⚡ Fun fact: I love turning ☕️ into code!

Post a Comment

CAN FEEDBACK
close