Secure CRUD Application with Laravel and Sanctum

Laravel, with its rich set of tools and features, simplifies building secure and scalable web applications. In this tutorial, we will create a secure CRUD (Create, Read, Update, Delete) application with authentication and authorization using Laravel and Sanctum.

Prerequisites

Before you begin, ensure you have the following:

  • PHP 8.0+ installed on your system.
  • Composer for dependency management.
  • Laravel 10+ installed globally or initialized in your project.
  • MySQL or any compatible database.
  • Basic knowledge of Laravel and REST APIs.


Step 1: Set Up Laravel Project

1.1 Install Laravel

Create a new Laravel project:

composer create-project laravel/laravel secure-crud-laravel-sanctum

Navigate into the project directory:

cd secure-crud-laravel-sanctum

1.2 Install Sanctum

Install Laravel Sanctum:

composer require laravel/sanctum

Publish the Sanctum configuration:

php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"


Run the database migrations for Sanctum:

php artisan migrate

Add Sanctum middleware to app/Http/Kernel.php:

protected $middlewareGroups = [
    'web' => [
        // ... other middlewares
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    ],

    'api' => [
        // ... other middlewares
        'auth:sanctum',
    ],
];


Step 2: Configure the Database

Update .env to match your database credentials:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=secure_crud
DB_USERNAME=root
DB_PASSWORD=your_password


Run the migrations:

php artisan migrate

Step 3: Set Up Authentication

3.1 Create the User Model and Factory

Ensure the User model exists in app/Models/User.php:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name', 'email', 'password',
    ];

    protected $hidden = [
        'password', 'remember_token',
    ];
}

3.2 Create Authentication Routes

Update routes/api.php:

use App\Http\Controllers\AuthController;

Route::post('/register', [AuthController::class, 'register']);
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->group(function () {
    Route::post('/logout', [AuthController::class, 'logout']);
});


Create the AuthController in app/Http/Controllers/AuthController.php:

namespace App\Http\Controllers;

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

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

        $user = User::where('email', $request->email)->first();

        if (!$user || !Hash::check($request->password, $user->password)) {
            return response()->json(['message' => 'Invalid credentials'], 401);
        }

        $token = $user->createToken('auth_token')->plainTextToken;

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

    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();
        return response()->json(['message' => 'Logged out successfully']);
    }
}


Step 4: Build the CRUD Functionality

4.1 Create the Resource Model

Run the Artisan command:

php artisan make:model Post -mcr

Update Post model in app/Models/Post.php:

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title', 'content', 'user_id',
    ];
}

4.2 Define Routes for CRUD Operations

Add the routes to routes/api.php:

use App\Http\Controllers\PostController;

Route::middleware('auth:sanctum')->group(function () {
    Route::resource('posts', PostController::class);
});

4.3 Implement the Controller Logic

Update PostController in app/Http/Controllers/PostController.php:

namespace App\Http\Controllers;

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

class PostController extends Controller
{
    public function index()
    {
        return Post::where('user_id', Auth::id())->get();
    }

    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|string',
            'content' => 'required|string',
        ]);

        return Post::create([
            'title' => $request->title,
            'content' => $request->content,
            'user_id' => Auth::id(),
        ]);
    }

    public function show(Post $post)
    {
        $this->authorize('view', $post);
        return $post;
    }

    public function update(Request $request, Post $post)
    {
        $this->authorize('update', $post);

        $post->update($request->only(['title', 'content']));
        return $post;
    }

    public function destroy(Post $post)
    {
        $this->authorize('delete', $post);

        $post->delete();
        return response()->json(['message' => 'Post deleted successfully']);
    }
}


Step 5: Test the Application

Use tools like Postman or Thunder Client to test the following endpoints:

Register: POST /api/register

Login: POST /api/login

Logout: POST /api/logout

CRUD: /api/posts (GET, POST, PUT, DELETE)


You have successfully built a secure CRUD application using Laravel and Sanctum. This project is extensible and serves as a foundation for more complex applications.  Hope this is helpful, and I apologize if there are any inaccuracies in the information provided.

Post a Comment for "Secure CRUD Application with Laravel and Sanctum"