Building a TODO App with API Authentication Using Laravel Sanctum

0 0
Read Time:4 Minute, 44 Second

A simple TODO app with API authentication using Laravel Sanctum, a powerful and straightforward package for managing API tokens in Laravel.

Introduction

Laravel is a popular PHP framework that simplifies the development of web applications. One of its standout features is Laravel Sanctum, which provides a hassle-free way to handle API authentication. We’ll use Sanctum to secure our TODO app, allowing users to authenticate, manage their tasks, and log out.

Prerequisites

To follow this tutorial, you should have:

  • A basic understanding of PHP and Laravel.
  • Laravel installed on your local development environment.

First, create a new Laravel project:

composer create-project --prefer-dist laravel/laravel todo-app
cd todo-app

Sanctum provides a simple solution for API token authentication. Install it via Composer:

composer require laravel/sanctum

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

Run the migrations to create the necessary database tables:

php artisan migrate

Next, we need to configure Sanctum to work with Laravel’s API routes. Open app/Http/Kernel.php and add Sanctum’s middleware to the api middleware group:

protected $middlewareGroups = [
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

Add the HasApiTokens trait to the User model, which is located in app/Models/User.php:

namespace App\Models;

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

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

    // Your existing code...
}

Create Authentication and TODO Controllers

php artisan make:controller API/AuthController
php artisan make:controller API/TodoController

Implement Authentication

In app/Http/Controllers/API/AuthController.php, implement registration, login, and logout methods:

namespace App\Http\Controllers\API;

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

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' => Hash::make($request->password),
        ]);

        return response()->json(['user' => $user, 'token' => $user->createToken('Personal Access Token')->plainTextToken]);
    }

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

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

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

        $user = Auth::user();
        $token = $user->createToken('Personal Access Token')->plainTextToken;

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

    public function logout(Request $request)
    {
        $request->user()->currentAccessToken()->delete();

        return response()->json(['message' => 'Logged out successfully']);
    }
}

Implement TODO Task Management

Create methods in app/Http/Controllers/API/TodoController.php for managing TODO tasks:

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Todo;
use Illuminate\Support\Facades\Validator;

class TodoController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:sanctum');
    }

    public function index()
    {
        return response()->json(auth()->user()->todos);
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|string|max:255',
            'completed' => 'boolean',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        $todo = auth()->user()->todos()->create([
            'title' => $request->title,
            'completed' => $request->completed ?? false,
        ]);

        return response()->json($todo, 201);
    }

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

        $validator = Validator::make($request->all(), [
            'title' => 'string|max:255',
            'completed' => 'boolean',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->errors(), 422);
        }

        $todo->update($request->only('title', 'completed'));

        return response()->json($todo);
    }

    public function destroy(Todo $todo)
    {
        $this->authorize('delete', $todo);

        $todo->delete();

        return response()->json(null, 204);
    }
}

Create the Todo Model and Migration

Generate the Todo model and migration:

php artisan make:model Todo -m

In the migration file (database/migrations/xxxx_xx_xx_create_todos_table.php), define the schema:

public function up()
{
    Schema::create('todos', function (Blueprint $table) {
        $table->id();
        $table->foreignId('user_id')->constrained()->onDelete('cascade');
        $table->string('title');
        $table->boolean('completed')->default(false);
        $table->timestamps();
    });
}

Run the migration to create the todos table:

php artisan migrate

In app/Models/Todo.php:

namespace App\Models;

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

class Todo extends Model
{
use HasFactory;

protected $fillable = ['title', 'completed'];

public function user()
{
return $this->belongsTo(User::class);
}
}

Define Policies for Authorization

Create a policy to handle authorization for TODO tasks:

php artisan make:policy TodoPolicy

In app/Policies/TodoPolicy.php:

public function update(User $user, Todo $todo)
{
    return $user->id === $todo->user_id;
}

public function delete(User $user, Todo $todo)
{
    return $user->id === $todo->user_id;
}

Register the policy in app/Providers/AuthServiceProvider.php:

protected $policies = [
    \App\Models\Todo::class => \App\Policies\TodoPolicy::class,
];

Define API Routes

Define the API routes in routes/api.php:

use App\Http\Controllers\API\AuthController;
use App\Http\Controllers\API\TodoController;

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

Route::middleware('auth:sanctum')->prefix('todos')->group(function () {
    Route::get('/', [TodoController::class, 'index']);
    Route::post('/', [TodoController::class, 'store']);
    Route::put('/{todo}', [TodoController::class, 'update']);
    Route::delete('/{todo}', [TodoController::class, 'destroy']);
});

Test Your API

You can test your API using tools like Postman or cURL. Here’s how:

Register a new user:

    curl -X POST http://your-app.test/api/register \
    -H "Content-Type: application/json" \
    -d '{"name": "John Doe", "email": "john@example.com", "password": "password"}'
    

    Login to get a token:

    curl -X POST http://your-app.test/api/login \
    -H "Content-Type: application/json" \
    -d '{"email": "john@example.com", "password": "password"}'
    

    Add a new TODO:

    curl -X POST http://your-app.test/api/todos \
    -H "Authorization: Bearer {your_token_here
    
    
    
    Happy
    Happy
    0 %
    Sad
    Sad
    0 %
    Excited
    Excited
    100 %
    Sleepy
    Sleepy
    0 %
    Angry
    Angry
    0 %
    Surprise
    Surprise
    0 %

    About Author

    Average Rating

    5 Star
    0%
    4 Star
    0%
    3 Star
    0%
    2 Star
    0%
    1 Star
    0%

    5 thoughts on “Building a TODO App with API Authentication Using Laravel Sanctum

    1. [url=https://opt24.store/product-category/shokoladnaya_i_orekhovaya_pasty/orekhovaya_pasta/ ]арахисовая паста оптом[/url] – сладости из азии оптом купить, батончики марс оптом

    Leave a Reply

    Your email address will not be published. Required fields are marked *