🔥 Kritik Hata 21:50 - 21:57 Arası

Muzibu Player - 419 CSRF Token Hataları

Müzik Dinlerken Tekrar Eden Hata Analizi

📅 9 Ocak 2026 - 21:50:01 - 21:57:00 (TR Saati) 🔴 20 Hata Tespit Edildi

📝 Basit Anlatım (Herkes İçin)

Sorun: Kullanıcı müzik dinlerken 20 kez hata aldı. Sistem "oturum süresi doldu" deyip istekleri kabul etmedi.

Neden? Kullanıcı uzun süre sayfada kaldı, arka planda müzik dinledi. Laravel'in güvenlik sistemi (CSRF token) sayfayı yeniden yüklemediyse 120 dakika sonra süresi doluyor. Müzik çalar arka planda istekler atmaya devam etti ama token geçersiz olduğu için hata aldı.

Benzetme:

Bir konsere girişte el damgası alıyorsunuz. 2 saat sonra damga solmuş oluyor. Tuvaletten dönerken kapıda güvenlik "damganız yok, giremezsiniz" diyor. Siz içeride müzik dinlerken damganız geçersiz hale gelmiş, yenilemeniz gerekiyor.

Etki: Müzik çalıyor ama:

  • Şarkı geçişlerinde "dinleme kaydı" tutulmuyor (track-start başarısız)
  • Debug loglar sunucuya gönderilemiyor (hata raporlama devre dışı)
  • AI asistan çalışmıyor (chat endpoint 419 hatası veriyor)
  • Kullanıcı deneyimi kesintili, bazı özellikler pasif

📊 Hata İstatistikleri

Toplam 419 Hatası

20

21:50 - 21:57 arası (7 dakika)

En Çok Etkilenen

debug-log

13 hata (toplam %65)

Kullanıcı IP

88.230.75.1

Macbook - Chrome 143

🎯 Hata Dağılımı (Endpoint Bazında)

🔴

POST /api/muzibu/debug-log

Debug log gönderme endpoint'i

13

%65

🟡

POST /api/muzibu/songs/*/track-start

Şarkı dinleme kaydı (analytics)

5

%25

🟠

POST /api/ai/v1/assistant/chat

AI müzik asistanı

2

%10

🔧 Teknik Detaylar (Geliştiriciler İçin)

🔐 419 Page Expired Hatası Nedir?

Laravel'in CSRF (Cross-Site Request Forgery) koruması. POST/PUT/DELETE isteklerinde _token parametresi zorunlu.

CSRF Token Ömrü:

SESSION_LIFETIME = 120 dakika (2 saat)

Hata Kodu:

HTTP 419 - "Page Expired"

📋 Örnek Access Log Satırları

🔴 Debug Log Hatası (13 kez tekrar etti):

88.230.75.1 - - [09/Jan/2026:18:50:01 +0000] "POST /api/muzibu/debug-log HTTP/2" 419 54227

🟡 Track Start Hatası (şarkı 18894, 26655, 26626, 26753):

88.230.75.1 - - [09/Jan/2026:18:50:01 +0000] "POST /api/muzibu/songs/18894/track-start HTTP/2" 419 1382

🟠 AI Asistan Hatası:

88.230.75.1 - - [09/Jan/2026:18:51:37 +0000] "POST /api/ai/v1/assistant/chat HTTP/2" 419 54234

⏱️ Hata Timeline

18:50

🎵 Şarkı 18894 oynatılmaya başlandı

→ track-start 419, debug-log 4x 419

18:51

🎵 Playlist 800 açıldı, şarkı 26655 oynatıldı

→ track-start 419, debug-log 2x 419

18:53

🎵 Şarkılar arasında geçiş (26626 → 26655)

→ track-start 2x 419, debug-log 4x 419

18:53

🔄 Sayfa yenilendi (playlists?page=2)

→ Yeni CSRF token alındı, hatalar durdu

📁 İlgili Dosyalar ve Config

⚙️ Session Config

config/session.php
'lifetime' => env('SESSION_LIFETIME', 120), // 120 dakika
'expire_on_close' => false,
'secure' => true, // HTTPS zorunlu
'same_site' => 'lax'

🛡️ CSRF Middleware

app/Http/Middleware/VerifyCsrfToken.php

→ Tüm POST/PUT/DELETE istekleri kontrol edilir

📜 JavaScript Player

public/themes/muzibu/js/player/*.js

→ CSRF token header'a ekleniyor ama token süresi dolunca yenilenmiyor

💡 Çözüm Önerileri

1️⃣

Otomatik CSRF Token Yenileme

Player JavaScript'inde token süresini kontrol et, dolmadan yenile.

JavaScript Pseudo-code:

// Token yenileme fonksiyonu
async function refreshCSRFToken() {
    const response = await fetch('/api/csrf-refresh');
    const data = await response.json();
    document.querySelector('meta[name="csrf-token"]').content = data.token;
}

// Her 60 dakikada bir yenile (lifetime 120 dakika)
setInterval(refreshCSRFToken, 60 * 60 * 1000);

// Sayfa focus aldığında da kontrol et
document.addEventListener('visibilitychange', () => {
    if (!document.hidden) refreshCSRFToken();
});

Avantaj: Kullanıcı kesintisiz dinlemeye devam eder

2️⃣

Belirli Endpoint'leri CSRF'den Muaf Tut

debug-log ve track-start gibi kritik olmayan endpoint'leri CSRF kontrolünden çıkar.

app/Http/Middleware/VerifyCsrfToken.php:

protected $except = [
    '/api/muzibu/debug-log',      // Debug loglar
    '/api/muzibu/songs/*/track-start', // Analytics
    // Dikkat: Güvenlik riski var, sadece read-only/analytics için!
];

⚠️ Uyarı: Güvenlik riski! Sadece veri toplama endpoint'leri için kullan.

3️⃣

Session Lifetime'ı Uzat

120 dakika yerine 480 dakika (8 saat) yap. Kullanıcı tüm gün kesintisiz dinleyebilir.

.env dosyası:

SESSION_LIFETIME=480  # 8 saat (480 dakika)

Not: Sunucu belleği artar, ancak kullanıcı deneyimi iyileşir.

4️⃣

Graceful Degradation (Yumuşak Düşme)

419 hatası alındığında kullanıcıyı uyar, sayfa yenilemesini öner.

JavaScript Pseudo-code:

// API call wrapper
async function apiCall(url, options) {
    const response = await fetch(url, options);

    if (response.status === 419) {
        showNotification('Oturum süresi doldu, sayfa yenileniyor...', 'warning');
        setTimeout(() => location.reload(), 2000);
        return null;
    }

    return response.json();
}

Avantaj: Kullanıcı ne olduğunu anlar, panik yapmaz.

🎯 Önerilen Aksiyonlar (Öncelik Sırasına Göre)

🥇

İlk Önce: Otomatik Token Yenileme

Player JavaScript'ine token refresh sistemi ekle. En temiz çözüm.

🥈

İkinci: Session Lifetime'ı Uzat

480 dakika yap, hızlı çözüm (1 satır .env değişikliği).

🥉

Üçüncü: Graceful Degradation Ekle

419 hatası için kullanıcı dostu uyarı göster.

⚠️

Opsiyonel: debug-log Endpoint'ini Muaf Tut

Sadece debug-log için, güvenlik riski düşük.

🔍 Ek Bulgular

⚠️ Database Connection Hatası (23:31)

Loglarda ayrıca "Too many connections" hatası görüldü. Bu ayrı bir sorun, CSRF ile ilgisi yok.

[2026-01-09 23:31:58] production.ERROR: Tenant başlatma hatası:
SQLSTATE[HY000] [1040] Too many connections

→ Bu ayrı bir performans sorunu, connection pool ayarlarına bakılmalı.

🔄 Thumbmaker 302 Redirect'leri

Bazı thumbmaker istekleri 302 redirect döndürüyor. Normal davranış (cache miss → generate → redirect).

→ Performance sorunu değil, ancak cache hit rate artırılabilir.