İçeriğe geç
Muhammet Şafak
Web Geliştirme 3 dk okuma

Laravel 7 ve Sanctum ile SPA kimlik doğrulama

Laravel Sanctum'un SPA kimlik doğrulamasını nasıl çözdüğünü, token tabanlı yaklaşımdan farkını somut örneklerle anlatıyorum.


SPA geliştirirken kimlik doğrulama her zaman rahatsız edici bir soruydu: oturum mu kullanayım, token mi? Laravel Passport büyük projeler için güçlü ama fazla ağır. JWT kütüphaneleri işe yarıyor ama her birinin kendine özgü ince noktaları var. Laravel 7 ile birlikte resmi olarak gelen Sanctum bu denklemi değiştirdi.

Sorun neydi?

Bir Vue SPA’sı ile aynı domain üzerindeki Laravel API’si arasında oturum yönetimi yapmak istiyorsunuz. Klasik web kimlik doğrulaması bu durumda çalışmıyor: SPA ayrı bir süreçte çalışıyor, laravel_session çerezi API isteklerine otomatik eklemiyor. Token tabanlı yaklaşımda ise tokeni güvenli saklamak (localStorage tehlikeli, httpOnly çerez elle kurulması gereken başka bir iş) ve yenilemek ayrı bir yük oluyor.

Sanctum iki senaryoya ayrı cevap veriyor: aynı kök domain (same-site) için çerez tabanlı oturum, mobil/üçüncü taraf için kişisel erişim token’ı. SPA için birinci yol daha temiz.

Kurulum ve yapılandırma

composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate

api middleware grubuna Sanctum’un middleware’ini eklemek gerekiyor:

// app/Http/Kernel.php
'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
    'throttle:60,1',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],

config/sanctum.php’deki stateful dizisine SPA’nın adresini ekliyorsunuz:

'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,127.0.0.1')),

Oturum açma akışı

SPA tarafında önce CSRF çerezi alınıyor, ardından kimlik bilgileri gönderiliyor:

// Önce CSRF çerezini al
await axios.get('/sanctum/csrf-cookie');

// Sonra giriş isteği
await axios.post('/login', {
    email: this.email,
    password: this.password,
});

/sanctum/csrf-cookie isteği, Sanctum’un XSRF-TOKEN çerezini tarayıcıya bırakıyor. Axios bunu otomatik olarak sonraki her istekte X-XSRF-TOKEN başlığı olarak gönderiyor. Laravel bu başlığı doğrulayarak CSRF saldırılarını önlüyor.

Giriş başarılı olursa Laravel oturumu sunucu tarafında başlatıyor ve oturum çerezi tarayıcıya dönüyor. Bundan sonraki her API isteği bu çerezi taşıdığı için kimlik doğrulanmış sayılıyor.

Korunan rotalarda auth:sanctum guard’ı kullanılıyor:

Route::middleware('auth:sanctum')->group(function () {
    Route::get('/user', fn () => auth()->user());
    Route::apiResource('posts', PostController::class);
});

Token tabanlı yaklaşımla karşılaştırma

Sanctum’un çerez modeli SPA için neden daha iyi? Birkaç somut neden:

Token saklamak için güvenli bir yer bulmak zorundasınız. localStorage XSS saldırılarına açık; httpOnly çerez güvenli ama o zaten çerez kullanıyorsunuz. Sanctum, Laravel’in yerleşik oturum altyapısını kullandığı için bu kararı sizi vermenize gerek kalmıyor.

Token refresh mekanizması yok. Sanctum’un çerez modeli standart Laravel oturumu gibi davranıyor; oturum süresi sunucuda yönetiliyor.

Aynı domain koşulu önemli. SPA ve API farklı subdomainlerde olabilir (app.example.com ve api.example.com), ama farklı ana domainlerde olamaz. Bu sınırın dışına çıktığınızda Sanctum token modeline geçmek gerekiyor.

Subdomain yapılandırması ve sık karşılaşılan tuzak

Geliştirme ortamında her şey çalışıp production’da kimlik doğrulama aniden başarısız olduğunda ilk bakacağınız yer SANCTUM_STATEFUL_DOMAINS değişkeni. .env dosyasında port numarasını eklemeyi unutmak çok sık yaşanan bir hata:

# Yanlış
SANCTUM_STATEFUL_DOMAINS=app.example.com

# Doğru (geliştirme ortamı için)
SANCTUM_STATEFUL_DOMAINS=localhost:3000,127.0.0.1:3000

Bunun yanı sıra SESSION_DOMAIN değişkenini subdomain kullanıyorsanız .example.com (baştaki nokta dahil) olarak ayarlamak gerekiyor; aksi hâlde çerez yalnızca api.example.com’a gönderiliyor, app.example.com’a değil.

Çıkış ve oturum yönetimi

Çıkış yapmak için /logout rotasına POST istek atmak yeterli; Laravel oturumu geçersiz kılıyor:

Route::post('/logout', function (Request $request) {
    Auth::guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    return response()->noContent();
});

Sanctum, SPA kimlik doğrulama sorununa Laravel’e özgü, sade bir cevap sunuyor. Passport kadar kapsamlı değil — OAuth2 flow’larına ihtiyacınız varsa yanlış araç. Ama kendi SPA’nızla kendi API’niz arasındaki oturumu güvenli kurmak için tam ölçek bu.

Etiketler: #Laravel#API
Paylaş:

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi