· Admin

Laravel ile Çoklu Kimlik Doğrulama (Multi-Auth) Sistemi

Birçok projede tek tip kullanıcı yeterli olmuyor. Admin paneli ayrı, müşteri girişi ayrı, satıcı paneli ayrı — her birinin kendi login sayfası ve yetkileri var. Laravel'in guard ve provider sistemi bu ihtiyacı zarif bir şekilde çözüyor.

Multi-Auth Neden Gerekli?

Tipik bir SaaS uygulamasında şu roller olabilir:

  • /admin/login → Yönetici paneli
  • /login → Normal kullanıcı girişi
  • /vendor/login → Satıcı paneli

Her rol farklı tabloda, farklı yetkilerde ve farklı dashboard'da. Tek users tablosuyla role sütunu eklemek de bir çözüm ama büyük projelerde guard bazlı ayrım çok daha temiz.

Admin Tablosu ve Model

Migration oluşturma:

php artisan make:migration create_admins_table
Schema::create('admins', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

Admin modeli:

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class Admin extends Authenticatable
{
    use Notifiable;

    protected $guard = 'admin';

    protected $fillable = ['name', 'email', 'password'];

    protected $hidden = ['password', 'remember_token'];
}

Kritik nokta: Authenticatable'ı extend etmek. Normal Model kullanırsanız auth çalışmaz.

Guard ve Provider Tanımlama

config/auth.php dosyasına yeni guard ekliyoruz:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'admin' => [
        'driver' => 'session',
        'provider' => 'admins',
    ],
],

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\Models\User::class,
    ],

    'admins' => [
        'driver' => 'eloquent',
        'model' => App\Models\Admin::class,
    ],
],

Guard = "kim girebilir" kuralları. Provider = "nereden bakılacak" ayarları.

Admin Login Controller

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function showLoginForm()
    {
        return view('admin.auth.login');
    }

    public function login(Request $request)
    {
        $request->validate([
            'email' => 'required|email',
            'password' => 'required|min:8',
        ]);

        $credentials = $request->only('email', 'password');

        if (Auth::guard('admin')->attempt($credentials, $request->boolean('remember'))) {
            $request->session()->regenerate();
            return redirect()->intended('/admin/dashboard');
        }

        return back()->withErrors([
            'email' => 'Giriş bilgileri hatalı.',
        ]);
    }

    public function logout(Request $request)
    {
        Auth::guard('admin')->logout();
        $request->session()->invalidate();
        $request->session()->regenerateToken();

        return redirect('/admin/login');
    }
}

Auth::guard('admin') ile hangi guard'ı kullanacağımızı belirtiyoruz. Varsayılan web guard'ıyla karışmaz.

Route Tanımları

use App\Http\Controllers\Admin\Auth\LoginController;

// Admin Routes
Route::prefix('admin')->name('admin.')->group(function () {
    // Guest routes
    Route::middleware('guest:admin')->group(function () {
        Route::get('/login', [LoginController::class, 'showLoginForm'])->name('login');
        Route::post('/login', [LoginController::class, 'login']);
    });

    // Protected routes
    Route::middleware('auth:admin')->group(function () {
        Route::post('/logout', [LoginController::class, 'logout'])->name('logout');
        Route::get('/dashboard', function () {
            return view('admin.dashboard');
        })->name('dashboard');
    });
});

auth:admin middleware'i sadece admin guard'ından giriş yapmış kullanıcıları geçirir.

Middleware ile Korumalı Route'lar

Guard belirterek route koruma:

// Sadece admin
Route::middleware('auth:admin')->group(function () {
    // admin paneli route'ları
});

// Sadece normal kullanıcı
Route::middleware('auth:web')->group(function () {
    // kullanıcı paneli route'ları
});

Blade template'lerde guard kontrolü:

@auth('admin')
    <a href="{{ route('admin.dashboard') }}">Admin Panel</a>
@endauth

@auth('web')
    <p>Hoş geldiniz, {{ auth()->user()->name }}</p>
@endauth

Redirect Ayarları

app/Http/Middleware/Authenticate.php veya bootstrap/app.php içinde guard'a göre redirect:

// Farklı guard'lar için farklı login sayfaları
protected function redirectTo(Request $request): ?string
{
    if ($request->is('admin/*')) {
        return route('admin.login');
    }

    return route('login');
}

Session Çakışmalarını Önleme

Bir kullanıcı hem web hem admin guard'ıyla aynı anda giriş yapabilir. Bu genelde sorun olmaz ama tek oturum istiyorsanız login sırasında diğer guard'ı logout yapabilirsiniz.

İleri Seviye: Spatie Permission

Daha karmaşık yetkilendirme için Spatie Laravel Permission paketi:

composer require spatie/laravel-permission
// Role ve permission tanımlama
$admin->assignRole('super-admin');
$admin->givePermissionTo('manage-users');

// Kontrol
if ($admin->hasRole('super-admin')) {
    // ...
}

Sonuç

Multi-auth sistemi büyük ve rol bazlı uygulamalarda kritik bir yapı. Laravel'in guard sistemi bunu çok temiz bir şekilde çözüyor. Guard'ları doğru tanımlayıp middleware'lerle koruma altına aldığınızda, her kullanıcı tipi kendi dünyasında güvenle çalışır.