aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Web Geliştirme

Laravel Middleware Nedir ve Nasıl Yazılır?

Laravel middleware, bir HTTP isteği uygulamanın iç katmanlarına ulaşmadan önce ve yanıt tarayıcıya dönmeden önce devreye giren bir filtre katmanıdır. İstek ile controller arasında duran bir dizi kapı gibi düşünebilirsiniz: her kapı isteği inceler, gerekirse durdurur, değiştirir veya bir sonraki kapıya geçirir. Kimlik doğrulama, oturum kontrolü, CSRF koruması ve dil algılama gibi işlerin neredeyse tamamı middleware ile yapılır.

İstek/yanıt zincirinde middleware'in rolü

Laravel'de gelen her istek bir "pipeline" (boru hattı) içinden geçer. Bu hat, soğan kabuğu modeline benzer: istek dıştan içe doğru her katmandan geçerek controller'a ulaşır, yanıt da aynı katmanlardan ters yönde geri döner. Bu sayede bir middleware hem istek öncesinde hem de yanıt sonrasında kod çalıştırabilir.

  • Önce çalışan kod: istek controller'a varmadan önce kontrol yapar (örneğin kullanıcı giriş yapmış mı?).
  • Sonra çalışan kod: yanıt üretildikten sonra başlık eklemek veya log atmak gibi işler yapar.

Zincirdeki sıra önemlidir. Örneğin oturumu başlatan middleware, oturuma bağlı doğrulamadan önce çalışmalıdır. Laravel bu sırayı varsayılan olarak mantıklı bir biçimde ayarlar ama kendi middleware'lerinizde sıraya dikkat etmeniz gerekir.

Middleware nasıl çalışır: temel yapı

Her middleware, bir handle metodu olan basit bir sınıftır. Bu metot iki parametre alır: gelen $request ve $next adında bir closure. $next($request) çağrısı, isteği zincirdeki bir sonraki halkaya geçirir.

public function handle(Request $request, Closure $next)
{
    // İstek öncesi mantık burada

    $response = $next($request);

    // Yanıt sonrası mantık burada

    return $response;
}

$next($request) satırından önce yazdığınız her şey istek controller'a ulaşmadan çalışır; sonra yazdığınız her şey ise yanıt geri dönerken çalışır. Eğer isteği hiç ilerletmek istemezseniz (örneğin yetki yoksa) $next'i çağırmadan doğrudan bir yanıt döndürürsünüz.

Kendi middleware'ini yazmak

Yeni bir middleware oluşturmanın en pratik yolu Artisan komutudur:

php artisan make:middleware EnsureTokenIsValid

Bu komut app/Http/Middleware/EnsureTokenIsValid.php dosyasını üretir. Diyelim ki belirli bir istek başlığında geçerli bir token olmayan istekleri reddetmek istiyoruz:

<?php

namespace App\Http\Middleware;

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

class EnsureTokenIsValid
{
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->header('X-Api-Token') !== config('services.api.token')) {
            abort(403, 'Geçersiz token.');
        }

        return $next($request);
    }
}

Burada token eşleşmezse abort(403) ile zincir hemen kesilir ve istek hiçbir controller'a ulaşmaz. Eşleşirse $next($request) ile akış devam eder.

Middleware'i kaydetmek (Laravel 11 ve 12)

Laravel 11 ile birlikte middleware kaydı eski app/Http/Kernel.php dosyasından bootstrap/app.php dosyasına taşındı. Burada üç temel yöntem var:

  • Global middleware: her isteğe uygulanır.
  • Grup middleware: web veya api gibi rota gruplarına eklenir.
  • Takma adlı (alias) middleware: tek tek rotalara ->middleware('alias') ile atanır.
// bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        // Tek rotalarda kullanmak için takma ad tanımla
        $middleware->alias([
            'token' => \App\Http\Middleware\EnsureTokenIsValid::class,
        ]);

        // web grubuna ekle
        $middleware->web(append: [
            \App\Http\Middleware\SetLocale::class,
        ]);
    })
    ->create();

Takma ad tanımladıktan sonra rotalarda şöyle kullanırsınız:

Route::get('/dashboard', DashboardController::class)
    ->middleware('token');

Not: Eğer hâlâ Laravel 10 veya öncesini kullanıyorsanız aynı kayıtlar app/Http/Kernel.php içindeki $middlewareAliases ve $middlewareGroups dizilerinde yapılır.

Parametre alan middleware

Middleware ek argümanlar da alabilir. Laravel'in yerleşik can ve rol kontrolü tam olarak bu mantıkla çalışır. handle metoduna $next'ten sonra parametre eklersiniz:

public function handle(Request $request, Closure $next, string $role): Response
{
    if (! $request->user()?->hasRole($role)) {
        abort(403);
    }

    return $next($request);
}

Rotada ise iki nokta üst üste ile değer geçirirsiniz:

Route::get('/admin', AdminController::class)
    ->middleware('role:editor');

Sık yapılan hatalar

  • $next($request)'i döndürmeyi unutmak: metot bir yanıt döndürmezse boş sayfa veya hata alırsınız. Erken çıkış yapmıyorsanız mutlaka return $next($request) yazın.
  • Yanlış sıra: oturuma bağlı işler oturum middleware'inden önce çalışırsa beklenmedik sonuçlar doğar.
  • Ağır iş yükü: middleware her istekte çalışır; veritabanı sorgularını ve dış API çağrılarını burada ölçülü kullanın, gerekirse önbelleğe alın.

Sık Sorulan Sorular

Middleware ile controller arasındaki fark nedir?

Controller belirli bir rotanın asıl iş mantığını yürütür. Middleware ise birden çok rotada tekrar eden, isteğe genel filtreleme/kontrol uygulayan çapraz kesen (cross-cutting) katmandır. Kimlik doğrulama gibi işler controller'a değil middleware'e aittir.

Bir rotaya birden fazla middleware ekleyebilir miyim?

Evet. ->middleware(['auth', 'token', 'role:editor']) şeklinde bir dizi verirsiniz; bunlar yazdığınız sırayla zincire eklenir.

Global middleware'i belirli rotalardan hariç tutabilir miyim?

Genellikle daha temiz çözüm, middleware'i global yapmak yerine ilgili gruba veya rotalara takma adla eklemektir. Böylece nerede çalıştığını açıkça kontrol edersiniz.

Laravel projende middleware mimarisini doğru kurmak mı istiyorsun? Kimlik doğrulamadan çok dilli yapı algılamaya kadar temiz ve test edilebilir bir middleware katmanı tasarlamana yardımcı olabilirim. Benimle iletişime geç.

Devamı için