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
go to this web-site [url=https://coinomiwallet.io/]coinomi download[/url]
[url=https://opt24.store/product-category/shokoladnaya_i_orekhovaya_pasty/orekhovaya_pasta/ ]арахисовая паста оптом[/url] – сладости из азии оптом купить, батончики марс оптом
view website [url=https://isrufus.org/]Rufus usb[/url]
view website https://hamsterkombat.zone/
[url=https://tronlink.cash/]tronlink wallet[/url] – tron wallet chrome, forgot tronlink password