Bu yazımızda Laravel ile proje geliştirirken sıklıkla kullanacağımız bir yapı olan middleware yapısının kullanımına değineceğiz.
Middleware yani ara katman, uygulamamıza gelen HTTP isteklerini incelemek, kontroller yapmak, filtrelemek için bize uygun bir yapı sağlayan katmandır.
Örnek vermek gerekirse Laravel kendi içerisinde hazır olarak kullanıcın kimliğini doğrulayan bir middleware barındırmaktadır. Bu middleware'i rotalara tanımladığımızda kullanıcı eğer oturum açmamışsa oturum sayfasına yönlendirir. Eğer oturum açmışsa ve kimliği doğrulanmışsa yapacağı işlemlere izin verir.
Mesela en çok kullanacağınız middleware'lerden biri de CSRF ara katmadınır. Form işlemlerinde formu kontrol etmek için bu ara katmanı kullanmak zorunludur.
Laravelde middleware dosyaları App/Http/Middleware klasöründe bulunur.
Yeni bir middleware tanımlamak için make:middleware Artisan komutunu kullanırız.
Bu komutlar terminal ekranında yazılıyor.
php artisan make:middleware denemeAraKatman
Bu komutu terminal ekranında çalıştırdığınızda Middleware oluşturuldu diye bir mesaj alırsınız. Yani şu ekrandaki gibi
Artık bir middleware yani ara katmanımız var. Bu katmana App/Http/Middleware klasöründen erişebiliriz.
Bu middleware ile atıyorum kullanıcı ismini kontrol edelim eğer ismi Zafer değilse kullanıcı programda hiçbir şey yapamasın.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class denemeAraKatman
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if ($request->input('userName') !== 'Zafer') {
return redirect('login');
}
return $next($request);
}
}
Gördüğünüz gibi midleware içindeki handle fonksiyonuna if koyarak eğer kullanıcıdan girilen isim Zafer değilse login sayfasına geri yönlendirme işlemi yaptık.
Ara katmanları (middleware) , Http istekleri uygulamanıza ulaşmadan önce geçmesi gereken bir nevi katman olarak düşünebilirsiniz.
Bir ara katman Http isteğini uygulamaya iletmeden önce veya ilettikten sonra işlemler yapıyor olabilir. Örneğin aşağıdaki ara katmanda uygulama işlenmeden önce yapılacak işlemler gerçekleştirilecektir.
<?php
namespace App\Http\Middleware;
use Closure;
class KatmandanOnceCalistir
{
public function handle($request, Closure $next){
// Yapılacak eylemlerreturn $next($request);
}
}
Aşağıdaki middleware ise istek Http tarafından işlendikten sonra görevini gerçekleştirir.
<?php
namespace App\Http\Middleware;
use Closure;
class KatmandanSonraCalistir
{
public function handle($request, Closure $next){
$response = $next($request);
// Gerçekleşecek eylemler
return $response;
}
}
Uygulamanıza yönelik her HTTP isteğinde bir middleware çalışmasını istiyorsanız middleware sınıfını App/Http/Kernel.php dosyasındaki $middleware dizisine eklemeniz yeterli olacaktır. Burada tanımladığınız her middleware sistem tarafından otomatik olarak çalıştırılmaktadır.
Tüm HTTP isteklerine değilde belli rotalara middleware koymak isteyebiliriz. Bunu yapmak için öncelikle App/Http/Kernel.php dosyasında $routeMiddleware dizisine kullanacağımız middleware ismini tanımlamalıyız.
Laravel 8'i ilk kurduğunuzda temel olarak routeMiddleware dizisi şu şekilde olacaktır.
<?php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,'can' => \Illuminate\Auth\Middleware\Authorize::class,'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
Bunları rotalarda ise şu şekilde kullanıyoruz. Mesela kullanıcı profiline gidecek ancak giriş yapmayan birinin profiline girmesi mümkün değil. Bunun için auth middleware'i kullanabiliriz. Rotalarda middleware kullanımı şu şekildedir.
<?php
Route::get('/profil', function () {
//
})->middleware('auth');
?>
Ayrıca rotalara eklediğimiz middleware fonksiyonu içine dizi göndererek birden fazla middleware kullanabiliriz.
Route::get('/profile', function () {
//
})->middleware(['auth','signed']);
Eğer kendiniz middleware eklediyseniz sınıf ı çağırarak da middleware yapısını kullanabilirsiniz.
<?php
use App\Http\Middleware\denemeMiddleware;
Route::get('/profile', function () {
//
})->middleware(denemeMiddleware::class);
?>
Bir middleware'in tüm rotalarda çalışıp bir rotada çalışmamasını isteyebilirsiniz. Ya da bir kaç rotada çalışmamasını.
Bu durumda wihoutMiddleware metodunu kullanabilirsiniz.
use App\Http\Middleware\denemeMiddleware;
Route::middleware([denemeMiddleware::class])->group(function () {
Route::get('/', function () {
//
});
Route::get('/profile', function () {
//
})->withoutMiddleware([denemeMiddleware::class]);
});
Bazen rotalara ulaşmak için bir kaç middleware'i tek bir çatı altında toplamak isteyebiliriz. Bunu Http/middleware/kernel.php içindeki $middlewareGroups dizisinde tanımlayarak yapabiliriz.
<?php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
Laracel ilk kurulduğu zaman web ve api rotalarına uygulamak isteyebileceğiniz bir kaç temel middleware grubunu otomatik yüklemektedir. Bu gruplar providers klasöründeki RouteServiceProvider dosyası tarafından içinde tanımlı olan rotalara otomatik olarak uygulanır.
Ara katman grupları rotalara şu şekilde uygulanır;
<?php
Route::get('/', function () {
//normal kullanım
})->middleware('web');
Route::middleware(['web'])->group(function () {
// ara katman grubuyla kullanım
});
Middleware ayrıca ek parametreler alabilirler. Mesela giriş yapan kullanıcının görevine yani rolune göre işlem yapmak istiyorsunuz o zaman kullanımı şöyle olur.
denemeMiddleware.php dosyamız
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class denemeAraKatman
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle (Request $request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// burda yetkisiz erişim sayfasına gider.
}
return $next($request);
}
}
Buda rota dosyamız
<?php
Route::put('/post/{id}', function ($id) {
//
})->middleware('role:editor');
?>
Eğer birden çok parametre kullanacaksak virgül ile ayırarak bu işlemi yapabiliriz.
Middleware yapısı laravelde gerçekten önemli bir yere sahiptir. Bu yapıyı iyi öğrenirseniz bir çok işlemi rahatlıkla gerçekleştirebilirsiniz.
Esen kalın...
Elinize sağlık çok güzel bir yazı olmuş paylaşımınız için teşekkürler
harika bir anlatım gerçekten tebrik ederim bir çok sayfada araştırıp bulamadığım veya eksik bulduğum şeyleri burada eksiksiz ve yalın bir anlatımla içerikleştirilmiş gerçekten teşekkür ederim
Zafer
26-October-2021Mükemmel anlatım için çok teşekkürler.