Lessons → Laravel Advanced → Lesson 1

Authentication with Sanctum

Laravel
⏱ 25 min read🔥 AdvancedNot completed

Laravel Sanctum provides a lightweight authentication system for SPAs, mobile apps, and simple token-based APIs. It's the most common auth solution for modern Laravel apps.

Install Sanctum

Terminal
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

Setup User Model

app/Models/User.php
<?php
use Laravel\Sanctum\HasApiTokens;

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

Auth Controller (Register + Login + Logout)

app/Http/Controllers/Api/AuthController.php
<?php
namespace App\Http\Controllers\Api;

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

class AuthController extends Controller
{
    public function register(Request $request)
    {
        $validated = $request->validate([
            'name'     => 'required|string|max:255',
            'email'    => 'required|email|unique:users',
            'password' => 'required|min:8|confirmed',
        ]);

        $user = User::create([
            'name'     => $validated['name'],
            'email'    => $validated['email'],
            'password' => Hash::make($validated['password']),
        ]);

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

        return response()->json([
            'user'         => $user,
            'access_token' => $token,
            'token_type'   => 'Bearer',
        ], 201);
    }

    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([
            'user'         => $user,
            'access_token' => $token,
            'token_type'   => 'Bearer',
        ]);
    }

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

    public function me(Request $request)
    {
        return response()->json($request->user());
    }
}

Routes

routes/api.php
<?php
use App\Http\Controllers\Api\AuthController;

// Public routes
Route::post('/register', [AuthController::class, 'register']);
Route::post('/login',    [AuthController::class, 'login']);

// Protected routes
Route::middleware('auth:sanctum')->group(function () {
    Route::post('/logout', [AuthController::class, 'logout']);
    Route::get('/me',      [AuthController::class, 'me']);
    Route::apiResource('posts', PostController::class);
});

Testing with Postman

HTTP Requests
# Register
POST /api/register
{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "password123",
  "password_confirmation": "password123"
}

# Login — get token
POST /api/login
{ "email": "john@example.com", "password": "password123" }

# Use token in header for protected routes
GET /api/me
Authorization: Bearer 1|abc123xyz...

Token Abilities (Scopes)

PHP
<?php
// Create token with specific abilities
$token = $user->createToken('mobile-app', ['posts:read', 'posts:write'])->plainTextToken;

// Check ability in controller
if ($request->user()->tokenCan('posts:write')) {
    // allowed
}
💡
Sanctum vs Passport: Use Sanctum for most apps — it's simpler. Use Passport only if you need full OAuth2 with authorization codes (e.g., "Login with MyApp" functionality).
← Back to Lessons Next Lesson →
🧠

Test your knowledge!

Take the Laravel quiz.

Take Quiz →