Laravel Middleware เจาะลึก: Authentication, Rate Limiting และ Custom Middleware ฉบับสมบูรณ์

คู่มือเจาะลึก Laravel Middleware ครอบคลุมการทำงานของ Authentication Middleware, Rate Limiting ด้วย Throttle, การสร้าง Custom Middleware และการลงทะเบียน Middleware ใน Laravel 12 พร้อมตัวอย่างโค้ดที่ใช้งานได้จริงในโปรดักชัน

คู่มือเจาะลึก Laravel Middleware ครอบคลุม Authentication, Rate Limiting และ Custom Middleware

Laravel Middleware ทำหน้าที่เป็นชั้นกรอง (Filtering Layer) ระหว่าง HTTP Request ที่เข้ามาและ Application Logic ทุก Request จะถูกส่งผ่าน Pipeline ของ Middleware Class ก่อนจะถึง Controller และทุก Response จะเดินทางกลับผ่าน Pipeline เดียวกัน การทำความเข้าใจกลไกนี้ถือเป็นสิ่งจำเป็นสำหรับการพัฒนา Laravel Application ที่มีความปลอดภัยและประสิทธิภาพสูงในปี 2026

Middleware โดยสรุป

Middleware ทำหน้าที่ดักจับ HTTP Request ก่อนที่จะถึง Route โดย Laravel 12 ลงทะเบียน Middleware ทั้งหมดใน bootstrap/app.php ผ่าน Fluent API ส่วน Built-in Middleware จะจัดการเรื่อง Authentication, CSRF Protection, Session Management และ Rate Limiting ให้โดยอัตโนมัติ

Pipeline ของ Laravel Middleware ทำงานอย่างไร

Laravel HTTP Kernel ประมวลผลทุก Request ผ่าน Stack ของ Middleware โดย Middleware แต่ละตัวจะรับ Request เข้ามา ดำเนินการตามตรรกะของตน จากนั้นส่ง Request ต่อไปยังชั้นถัดไปผ่าน $next($request) หรือตัดวงจร Pipeline ด้วยการคืนค่า Response โดยตรง

สถาปัตยกรรมนี้เป็นไปตาม Chain of Responsibility Pattern โดย Middleware สามารถทำงาน ก่อน ที่ Request จะถึง Controller (เช่น การตรวจสอบ Authentication) ทำงาน หลัง จากที่ Response ถูกสร้างขึ้น (เช่น การเพิ่ม Header) หรือทำงานทั้งสองช่วงเวลา

app/Http/Middleware/LogRequestTime.phpphp
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;

class LogRequestTime
{
    public function handle(Request $request, Closure $next): Response
    {
        $start = microtime(true);          // Capture start time

        $response = $next($request);       // Pass to next middleware

        $duration = microtime(true) - $start;
        Log::info('Request completed', [
            'url'      => $request->url(),
            'method'   => $request->method(),
            'duration' => round($duration * 1000, 2) . 'ms',
        ]);

        return $response;                  // Return response up the stack
    }
}

Middleware ตัวนี้ครอบ Request ไว้ทั้งสองด้าน กล่าวคือจะบันทึกเวลาเริ่มต้น ก่อน การประมวลผล และบันทึกระยะเวลา หลัง จากที่ Response ถูกส่งกลับมา รูปแบบ Before/After นี้เป็นหัวใจสำคัญของการทำงานของ Middleware

Authentication Middleware: การปกป้อง Route

Laravel มาพร้อมกับ auth Middleware Alias ซึ่ง Map ไปยัง Illuminate\Auth\Middleware\Authenticate การใช้งาน Middleware นี้กับ Route ใดก็ตามจะทำให้มั่นใจได้ว่าเฉพาะผู้ใช้ที่ผ่านการยืนยันตัวตนแล้วเท่านั้นที่สามารถเข้าถึงได้ ผู้ใช้ที่ไม่ได้ยืนยันตัวตนจะได้รับ 401 Response (API) หรือถูก Redirect ไปยังหน้า Login (Web)

routes/web.phpphp
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\ProfileController;

// Single route protection
Route::get('/dashboard', [DashboardController::class, 'index'])
    ->middleware('auth');

// Group protection for multiple routes
Route::middleware('auth')->group(function () {
    Route::get('/profile', [ProfileController::class, 'show']);
    Route::put('/profile', [ProfileController::class, 'update']);
    Route::delete('/profile', [ProfileController::class, 'destroy']);
});

Multi-Guard Authentication

Application ที่มีผู้ใช้หลายประเภท (Admin Panel, Customer Area, API) จะได้รับประโยชน์จากการยืนยันตัวตนแบบ Guard-Based โดย auth Middleware รับพารามิเตอร์ Guard เพื่อระบุว่าจะใช้ Authentication Driver ตัวใด

routes/api.phpphp
// API routes use the 'sanctum' guard
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', fn (Request $request) => $request->user());
    Route::apiResource('/orders', OrderController::class);
});

// routes/web.php
// Admin routes use a custom 'admin' guard
Route::middleware('auth:admin')->prefix('admin')->group(function () {
    Route::get('/dashboard', [AdminController::class, 'index']);
    Route::get('/users', [AdminController::class, 'users']);
});

พารามิเตอร์ Guard หลังเครื่องหมาย Colon จะบอก Laravel ว่าให้ตรวจสอบกับ Authentication Configuration ตัวใด วิธีนี้ช่วยให้ตรรกะการยืนยันตัวตนเป็นระเบียบและแยกส่วนกันอย่างชัดเจนในแต่ละส่วนของ Application

Guest Middleware

guest Middleware เป็นตรงข้ามของ auth กล่าวคือจะอนุญาตให้เฉพาะผู้ใช้ที่ยังไม่ได้ยืนยันตัวตนผ่านเข้าไปได้เท่านั้น การนำไปใช้กับ Route ของหน้า Login และ Registration จะป้องกันไม่ให้ผู้ใช้ที่ยืนยันตัวตนแล้วเข้าถึงหน้าเหล่านั้น

Rate Limiting ด้วย Throttle Middleware

Laravel Middleware Rate Limiting ปกป้อง Route จากการถูกใช้งานเกินขอบเขตด้วย throttle Middleware ในตัว รูปแบบที่ง่ายที่สุดรับพารามิเตอร์สองตัว ได้แก่ จำนวน Request สูงสุดและกรอบเวลาเป็นนาที

routes/api.phpphp
// Allow 60 requests per minute per user
Route::middleware('throttle:60,1')->group(function () {
    Route::get('/posts', [PostController::class, 'index']);
    Route::get('/posts/{post}', [PostController::class, 'show']);
});

// Stricter limit for write operations
Route::middleware(['auth:sanctum', 'throttle:10,1'])->group(function () {
    Route::post('/posts', [PostController::class, 'store']);
    Route::put('/posts/{post}', [PostController::class, 'update']);
});

Named Rate Limiters สำหรับการควบคุมขั้นสูง

การกำหนด Named Rate Limiters ใน AppServiceProvider จะให้การควบคุมที่ละเอียดยิ่งขึ้นตามบริบทของผู้ใช้ วิธีนี้มีความยืดหยุ่นมากกว่าการใช้พารามิเตอร์ Throttle แบบ Inline

app/Providers/AppServiceProvider.phpphp
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Http\Request;

public function boot(): void
{
    // API rate limiter with tiered access
    RateLimiter::for('api', function (Request $request) {
        $user = $request->user();

        if ($user?->hasSubscription('enterprise')) {
            return Limit::perMinute(500)->by($user->id);   // Enterprise: 500/min
        }

        if ($user) {
            return Limit::perMinute(100)->by($user->id);   // Authenticated: 100/min
        }

        return Limit::perMinute(20)->by($request->ip());   // Anonymous: 20/min
    });

    // Login limiter to prevent brute force
    RateLimiter::for('login', function (Request $request) {
        return Limit::perMinute(5)
            ->by($request->ip())                            // Key by IP address
            ->response(function () {                        // Custom exceeded response
                return response()->json([
                    'message' => 'Too many login attempts. Try again in a minute.',
                ], 429);
            });
    });
}

การนำ Named Limiters ไปใช้กับ Route จะใช้ Syntax throttle:name ดังนี้

routes/api.phpphp
Route::middleware('throttle:api')->group(function () {
    Route::apiResource('/posts', PostController::class);
});

// routes/web.php
Route::middleware('throttle:login')
    ->post('/login', [AuthController::class, 'login']);

Tiered Rate Limiter ข้างต้นเป็นรูปแบบที่ใช้จริงในโปรดักชัน โดยผู้ใช้ระดับ Enterprise จะได้รับ Limit ที่สูงกว่า ผู้ใช้ที่ยืนยันตัวตนแล้วจะได้รับ Limit ระดับปานกลาง และ Request จากผู้ใช้ที่ไม่ระบุตัวตนจะถูกจำกัดอย่างเข้มงวด เมธอด by() กำหนด Rate Limit Key โดยใช้ User ID สำหรับผู้ใช้ที่ยืนยันตัวตนแล้ว และ IP Address เป็นทางเลือกสำรอง

พร้อมที่จะพิชิตการสัมภาษณ์ Laravel แล้วหรือยังครับ?

ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ

การสร้าง Custom Middleware ตั้งแต่เริ่มต้น

การสร้าง Custom Middleware ครอบคลุมสถานการณ์ที่ Built-in Middleware ไม่สามารถจัดการได้ คำสั่ง make:middleware ของ Artisan จะสร้าง Class ใหม่พร้อมโครงสร้างที่ถูกต้อง

bash
php artisan make:middleware EnsureUserHasRole

Role-Based Access Control Middleware

รูปแบบ Custom Middleware ที่พบบ่อยคือการบังคับใช้ Role-Based Authorization ที่ระดับ Route โดยรับชื่อ Role เป็นพารามิเตอร์

app/Http/Middleware/EnsureUserHasRole.phpphp
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureUserHasRole
{
    public function handle(Request $request, Closure $next, string ...$roles): Response
    {
        $user = $request->user();

        if (! $user || ! $user->hasAnyRole($roles)) {
            abort(403, 'Insufficient permissions.');
        }

        return $next($request);
    }
}

พารามิเตอร์แบบ Variadic ...$roles อนุญาตให้ส่ง Role หลายตัวคั่นด้วยเครื่องหมายจุลภาค การลงทะเบียนและการใช้งานมีลักษณะดังนี้

bootstrap/app.phpphp
->withMiddleware(function (Middleware $middleware) {
    $middleware->alias([
        'role' => \App\Http\Middleware\EnsureUserHasRole::class,
    ]);
})

// routes/web.php
Route::middleware('role:admin')->group(function () {
    Route::get('/admin', [AdminController::class, 'index']);
});

// Multiple roles: admin OR editor can access
Route::middleware('role:admin,editor')->group(function () {
    Route::resource('/articles', ArticleController::class);
});

Request Transformation Middleware

Middleware สามารถแก้ไข Request ก่อนที่จะถึง Controller ตัวอย่างเช่น JSON API Middleware ที่บังคับใช้ Content Type Header และตัดช่องว่างจาก String Input

app/Http/Middleware/ApiRequestSanitizer.phpphp
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class ApiRequestSanitizer
{
    public function handle(Request $request, Closure $next): Response
    {
        // Reject non-JSON requests on API routes
        if (! $request->expectsJson() && $request->isMethod('POST')) {
            return response()->json(
                ['error' => 'Content-Type must be application/json'],
                415
            );
        }

        // Trim all string inputs
        $input = $request->all();
        array_walk_recursive($input, function (&$value) {
            if (is_string($value)) {
                $value = trim($value);
            }
        });
        $request->merge($input);

        return $next($request);
    }
}

Middleware ตัวนี้จัดการสองเรื่องพร้อมกัน ได้แก่ การตรวจสอบ Content Type สำหรับ POST Request และการทำความสะอาด String Input ทั้งหมดด้วยการตัดช่องว่าง

การลงทะเบียน Middleware ใน Laravel 12

Laravel 12 รวมศูนย์การลงทะเบียน Middleware ทั้งหมดไว้ใน bootstrap/app.php ซึ่งมาแทนที่แนวทาง app/Http/Kernel.php แบบเดิมที่ใช้ก่อน Laravel 11

bootstrap/app.phpphp
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        // Global middleware (runs on every request)
        $middleware->append(
            \App\Http\Middleware\LogRequestTime::class
        );

        // Add to the 'web' middleware group
        $middleware->web(append: [
            \App\Http\Middleware\TrackPageViews::class,
        ]);

        // Add to the 'api' middleware group
        $middleware->api(prepend: [
            \App\Http\Middleware\ApiRequestSanitizer::class,
        ]);

        // Register aliases for route-level use
        $middleware->alias([
            'role'       => \App\Http\Middleware\EnsureUserHasRole::class,
            'subscribed' => \App\Http\Middleware\EnsureUserIsSubscribed::class,
        ]);

        // Control execution order
        $middleware->priority([
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\Auth\Middleware\Authenticate::class,
            \App\Http\Middleware\EnsureUserHasRole::class,
        ]);
    })
    ->create();

Array priority มีความสำคัญเมื่อ Middleware หลายตัวถูกกำหนดให้กับ Route เดียวกัน Laravel จะเรียงลำดับการทำงานตามรายการนี้ เพื่อให้มั่นใจว่า Session จะเริ่มทำงานก่อน Authentication และ Authentication จะเสร็จสิ้นก่อนการตรวจสอบ Role

ลำดับการทำงานของ Middleware

Middleware ทำงานตามลำดับที่ลงทะเบียนไว้ สำหรับ Middleware ระดับ Route นั้น Array priority จะ Override ลำดับเริ่มต้น ควรวาง Authentication Middleware ไว้ก่อน Authorization Middleware เสมอ เพื่อหลีกเลี่ยงการตรวจสอบ Role กับ Request ที่ยังไม่ได้ยืนยันตัวตน

Terminable Middleware สำหรับงานหลังส่ง Response

Terminable Middleware จะดำเนินการตรรกะ หลัง จากที่ Response ถูกส่งไปยังผู้ใช้แล้ว สิ่งนี้มีประโยชน์สำหรับการบันทึก Log, Analytics หรืองาน Cleanup ที่ไม่ควรบล็อกการตอบสนองต่อผู้ใช้

app/Http/Middleware/CollectAnalytics.phpphp
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\Response;

class CollectAnalytics
{
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request);  // Pass through without delay
    }

    public function terminate(Request $request, Response $response): void
    {
        // Runs after response is sent to client
        DB::table('analytics')->insert([
            'path'        => $request->path(),
            'method'      => $request->method(),
            'status_code' => $response->getStatusCode(),
            'user_id'     => $request->user()?->id,
            'ip'          => $request->ip(),
            'created_at'  => now(),
        ]);
    }
}

เมธอด terminate จะรับทั้ง Request เดิมและ Response สุดท้าย ควรลงทะเบียน Middleware นี้เป็น Singleton ใน AppServiceProvider เพื่อให้มั่นใจว่า Instance เดียวกันจะจัดการทั้งเมธอด handle() และ terminate()

รูปแบบ Middleware สำหรับใช้งานจริงในโปรดักชัน

มีรูปแบบ Middleware หลายรูปแบบที่ปรากฏอย่างสม่ำเสมอใน Laravel Application ที่ใช้งานจริงในโปรดักชัน

Maintenance Mode Bypass อนุญาตให้ IP ภายในเข้าถึง Application ในระหว่างการบำรุงรักษา

app/Http/Middleware/MaintenanceBypass.phpphp
class MaintenanceBypass
{
    private array $allowedIps = ['192.168.1.0/24', '10.0.0.1'];

    public function handle(Request $request, Closure $next): Response
    {
        if (app()->isDownForMaintenance()) {
            foreach ($this->allowedIps as $ip) {
                if ($request->ip() === $ip) {
                    return $next($request);
                }
            }
        }

        return $next($request);
    }
}

Security Headers เพิ่ม HSTS, Content Security Policy และ Header อื่น ๆ ในทุก Response

app/Http/Middleware/SecurityHeaders.phpphp
class SecurityHeaders
{
    public function handle(Request $request, Closure $next): Response
    {
        $response = $next($request);

        $response->headers->set('X-Content-Type-Options', 'nosniff');
        $response->headers->set('X-Frame-Options', 'SAMEORIGIN');
        $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
        $response->headers->set(
            'Strict-Transport-Security',
            'max-age=31536000; includeSubDomains'
        );

        return $response;
    }
}

รูปแบบเหล่านี้แสดงให้เห็นตำแหน่งหลักสองตำแหน่งของ Middleware ได้แก่ ก่อน Request (Maintenance Bypass ตรวจสอบ IP และอาจบล็อก) และ หลัง Response (Security Headers แก้ไข Response ที่ส่งออกไป)

พร้อมที่จะพิชิตการสัมภาษณ์ Laravel แล้วหรือยังครับ?

ฝึกฝนด้วยตัวจำลองแบบโต้ตอบ, flashcards และแบบทดสอบเทคนิคครับ

สรุป

  • Laravel Middleware ทำงานเป็น Pipeline โดยแต่ละ Class จะประมวลผล Request ดำเนินการกับมัน แล้วส่งต่อหรือตัดวงจรด้วยการคืน Response
  • auth Middleware ปกป้อง Route ด้วย Guard-Based Authentication รองรับผู้ใช้หลายประเภทผ่าน Syntax auth:guard
  • Rate Limiting ผ่าน throttle Middleware และการกำหนด Named RateLimiter::for() ช่วยให้สามารถควบคุมการเข้าถึงแบบแบ่งระดับตามบริบทของผู้ใช้
  • Custom Middleware จัดการ Cross-Cutting Concerns เช่น การตรวจสอบ Role, การทำความสะอาด Request และ Security Headers โดยไม่ทำให้ Controller รกรุงรัง
  • การลงทะเบียน Middleware ทั้งหมดใน Laravel 12 ทำใน bootstrap/app.php ผ่าน Fluent API โดยใช้ priority ควบคุมลำดับการทำงาน
  • Terminable Middleware ทำงานหลังส่ง Response (Analytics, Logging) โดยไม่กระทบต่อ Latency ที่ผู้ใช้รับรู้
  • พารามิเตอร์ของ Middleware ผ่าน Syntax :param ทำให้ Route Definition มีความชัดเจนและ Middleware Class สามารถนำกลับมาใช้ซ้ำได้ในบริบทที่แตกต่างกัน

เริ่มฝึกซ้อมเลย!

ทดสอบความรู้ของคุณด้วยตัวจำลองสัมภาษณ์และแบบทดสอบเทคนิคครับ

แท็ก

#laravel
#middleware
#authentication
#rate-limiting
#php

แชร์

บทความที่เกี่ยวข้อง

คำถามสัมภาษณ์งาน Laravel และ PHP - คู่มือฉบับสมบูรณ์

25 คำถามสัมภาษณ์งาน Laravel และ PHP ยอดนิยมในปี 2026

รวม 25 คำถามสัมภาษณ์งาน Laravel และ PHP ที่พบบ่อยที่สุด ครอบคลุม Service Container, Eloquent ORM, middleware, queues และการ deploy ระบบ production พร้อมคำตอบและตัวอย่างโค้ดครบถ้วน

บทเรียน Laravel 11 สร้างแอปพลิเคชันสมบูรณ์

Laravel 11: สร้างแอปพลิเคชันสมบูรณ์ตั้งแต่เริ่มต้น

คู่มือครบวงจรสำหรับสร้างแอปพลิเคชัน Laravel 11 พร้อมระบบยืนยันตัวตน, REST API, Eloquent ORM และการ Deploy บทเรียนเชิงปฏิบัติสำหรับนักพัฒนาระดับเริ่มต้นถึงกลาง

Symfony 7 และ API Platform 4 สำหรับการพัฒนา REST API แบบ professional

Symfony 7 กับ API Platform: แนวทางปฏิบัติที่ดีที่สุดสำหรับ REST API

คู่มือเชิงลึกสำหรับการสร้าง REST API ด้วย Symfony 7 และ API Platform 4 ครอบคลุม Resource configuration, State Processor, Serialization Groups, Security และการปรับแต่ง performance ด้วยตัวอย่างโค้ดที่ใช้งานได้จริง