Laravel Framework

Authentication & Authorization Basics

20 min Lesson 11 of 45

Introduction to Authentication in Laravel

Authentication is the process of verifying the identity of a user, while authorization determines what actions a user can perform. Laravel provides a complete authentication system out of the box, making it easy to implement secure user login, registration, and access control.

Laravel Authentication Starters

Laravel offers several starter kits for authentication:

  • Laravel Breeze: Minimal authentication scaffolding with Blade templates
  • Laravel Jetstream: Full-featured authentication with teams support
  • Laravel Fortify: Headless authentication backend (API-friendly)
  • Laravel Sanctum: API token authentication for SPAs
Note: Laravel Breeze is the simplest option and perfect for learning. It includes login, registration, password reset, email verification, and password confirmation.

Installing Laravel Breeze

To install Laravel Breeze in a fresh Laravel application:

# Install Breeze via Composer composer require laravel/breeze --dev # Install Breeze scaffolding php artisan breeze:install # Options: # - Blade (default) # - React # - Vue # - API (for headless applications) # Compile assets npm install npm run dev # Run migrations php artisan migrate

After installation, Breeze provides the following routes automatically:

// Authentication routes /login - Login form /register - Registration form /forgot-password - Password reset request /reset-password - Password reset form /verify-email - Email verification /confirm-password - Password confirmation /logout - Logout (POST) // Protected routes /dashboard - User dashboard (auth required)

The User Model

Laravel comes with a User model that implements authentication contracts:

<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use Notifiable; protected $fillable = [ 'name', 'email', 'password', ]; protected $hidden = [ 'password', 'remember_token', ]; protected $casts = [ 'email_verified_at' => 'datetime', 'password' => 'hashed', // Laravel 10+ ]; }
Tip: The User model extends Authenticatable, which provides all authentication functionality. The Notifiable trait allows sending notifications to users.

Manual Authentication

You can manually authenticate users without using starter kits:

<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class LoginController extends Controller { public function showLoginForm() { return view('auth.login'); } public function login(Request $request) { // Validate credentials $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); // Attempt to authenticate if (Auth::attempt($credentials, $request->boolean('remember'))) { // Regenerate session to prevent fixation $request->session()->regenerate(); return redirect()->intended('dashboard'); } // Authentication failed return back()->withErrors([ 'email' => 'The provided credentials do not match our records.', ])->onlyInput('email'); } public function logout(Request $request) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/'); } }

Protecting Routes with Authentication

Use the auth middleware to require authentication:

<?php use App\Http\Controllers\DashboardController; use Illuminate\Support\Facades\Route; // Protect single route Route::get('/dashboard', [DashboardController::class, 'index']) ->middleware('auth'); // Protect multiple routes with group Route::middleware(['auth'])->group(function () { Route::get('/dashboard', [DashboardController::class, 'index']); Route::get('/profile', [ProfileController::class, 'show']); Route::get('/settings', [SettingsController::class, 'index']); }); // Protect routes in controller constructor class DashboardController extends Controller { public function __construct() { $this->middleware('auth'); // Except specific methods $this->middleware('auth')->except(['index', 'show']); // Only specific methods $this->middleware('auth')->only(['create', 'store', 'edit', 'update']); } }

Accessing the Authenticated User

Retrieve the currently authenticated user in multiple ways:

<?php use Illuminate\Support\Facades\Auth; use Illuminate\Http\Request; // Using Auth facade $user = Auth::user(); $id = Auth::id(); // Check if authenticated if (Auth::check()) { // User is logged in } // Using Request object public function index(Request $request) { $user = $request->user(); } // Using auth() helper $user = auth()->user(); $id = auth()->id(); // In Blade views @auth <p>Welcome, {{ auth()->user()->name }}</p> @endauth @guest <p>Please login</p> @endguest

Email Verification

Laravel provides built-in email verification functionality:

<?php namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; // Implement MustVerifyEmail contract class User extends Authenticatable implements MustVerifyEmail { // ... } // In routes/web.php - protect routes with verified middleware Route::middleware(['auth', 'verified'])->group(function () { Route::get('/dashboard', [DashboardController::class, 'index']); });
Note: Email verification requires mail configuration in your .env file. For local development, use Mailtrap or log driver.

Password Reset

Laravel Breeze includes password reset out of the box. Here's how it works manually:

<?php use Illuminate\Support\Facades\Password; // Send password reset link public function sendResetLink(Request $request) { $request->validate(['email' => 'required|email']); $status = Password::sendResetLink( $request->only('email') ); return $status === Password::RESET_LINK_SENT ? back()->with(['status' => __($status)]) : back()->withErrors(['email' => __($status)]); } // Reset password public function resetPassword(Request $request) { $request->validate([ 'token' => 'required', 'email' => 'required|email', 'password' => 'required|min:8|confirmed', ]); $status = Password::reset( $request->only('email', 'password', 'password_confirmation', 'token'), function ($user, $password) { $user->password = $password; $user->save(); } ); return $status === Password::PASSWORD_RESET ? redirect()->route('login')->with('status', __($status)) : back()->withErrors(['email' => [__($status)]]); }

Authentication Guards

Guards define how users are authenticated for each request. Laravel supports multiple guards for different user types:

// config/auth.php return [ 'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ 'driver' => 'session', 'provider' => 'admins', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'admins' => [ 'driver' => 'eloquent', 'model' => App\Models\Admin::class, ], ], ];

Using different guards:

<?php // Use specific guard if (Auth::guard('admin')->attempt($credentials)) { // Admin authenticated } // Logout from specific guard Auth::guard('admin')->logout(); // Protect routes with specific guard Route::middleware(['auth:admin'])->group(function () { Route::get('/admin/dashboard', [AdminController::class, 'index']); }); // Get user from specific guard $admin = Auth::guard('admin')->user();

Basic Authorization with Gates

Authorization determines what authenticated users can do. Gates are simple closures for authorization logic:

<?php // app/Providers/AuthServiceProvider.php namespace App\Providers; use App\Models\Post; use App\Models\User; use Illuminate\Support\Facades\Gate; class AuthServiceProvider extends ServiceProvider { public function boot(): void { // Define a gate Gate::define('update-post', function (User $user, Post $post) { return $user->id === $post->user_id; }); // Gate with no model (check user property) Gate::define('manage-users', function (User $user) { return $user->is_admin; }); } } // Using gates in controllers public function update(Request $request, Post $post) { Gate::authorize('update-post', $post); // Alternative: throws 403 if unauthorized if (Gate::denies('update-post', $post)) { abort(403); } // Or use allows() if (Gate::allows('update-post', $post)) { // Update the post } } // In Blade views @can('update-post', $post) <a href="{{ route('posts.edit', $post) }}">Edit</a> @endcan
Tip: Gates are best for simple authorization checks. For more complex authorization logic, use Policies (covered in next lesson).

Exercise 1: Create Authentication System

Install Laravel Breeze in a fresh Laravel project and customize the registration form to include a "phone" field.

  1. Install Breeze with composer require laravel/breeze --dev
  2. Run php artisan breeze:install
  3. Add "phone" column to users migration
  4. Update registration form view
  5. Update User model fillable array
  6. Test registration with the new field

Exercise 2: Implement Custom Authentication

Create a custom login controller without using Breeze that authenticates users by username instead of email.

  1. Create LoginController with showLoginForm() and login() methods
  2. Validate username and password fields
  3. Use Auth::attempt() with username field
  4. Regenerate session on success
  5. Redirect to dashboard or return validation errors
  6. Create corresponding login view

Exercise 3: Multi-Guard Authentication

Set up a multi-guard authentication system with separate guards for regular users and admins.

  1. Create Admin model and migration
  2. Add "admin" guard in config/auth.php
  3. Create admin authentication controller
  4. Add admin routes protected by auth:admin middleware
  5. Test login as both user and admin
  6. Ensure guards don't interfere with each other

Summary

In this lesson, you learned:

  • Laravel authentication starter kits (Breeze, Fortify, Jetstream)
  • Installing and using Laravel Breeze
  • Manual authentication with Auth facade
  • Protecting routes with auth middleware
  • Accessing authenticated users
  • Email verification and password reset
  • Authentication guards for multiple user types
  • Basic authorization with Gates
Next Lesson: We'll dive deeper into authorization with Policies and learn about middleware customization.