LocalStorage Açığı
B2B SaaS uygulamaları geliştirirken, kimlik doğrulama ilk savunma hattıdır. Next.js frontend’in bir Laravel API ile iletişimi için en yaygın mimari desen, JSON Web Tokens (JWT) kullanmaktır. Ancak, geliştiricilerin yaptığı en kritik hata, bu JWT’yi API yük bilgisinde döndürmek ve tarayıcının localStorage‘ında saklamaktır.
Hassas token’ların localStorage veya sessionStorage‘da saklanması, tüm kullanıcı tabanınızı Cross-Site Scripting (XSS) saldırılarına maruz bırakır. Eğer kötü niyetli bir script, ön yüzünüze (belki de zararlı bir üçüncü parti NPM paketi aracılığıyla) enjekte edilirse, bu script kolayca localStorage‘ı okuyabilir, adminin JWT’sini çalabilir ve oturumu tamamen ele geçirebilir. Kurumsal platformlar için bu kabul edilemez bir güvenlik riskidir.
Kurumsal Çözüm: HttpOnly ve SameSite Çerezleri
Dayanıklı ve güvenli bir mimari inşa etmek için, frontend JavaScript’in kimlik doğrulama token’ına doğrudan erişimi olmamalıdır. Bunun yerine, Laravel backend’i JWT’yi yanıtla birlikte HttpOnly, Secure çerezi olarak iliştirmelidir.
HttpOnly çerezi, JavaScript içerisinde document.cookie ile okunamaz ve bu da XSS ile token çalınmasını geçersiz kılar. Ayrıca, SameSite=Strict özelliğinin ayarlanması, çerezin yalnızca birinci taraf bağlamında gönderilmesini sağlar ve Cross-Site Request Forgery (CSRF) saldırılarını azaltır.
Adım 1: Laravel Kimlik Doğrulama Kontrolcüsü
Başarılı bir oturum açma sonrasında token’ı güvenli bir şekilde vermek için aşağıdaki kodu kullanın. Bu kod, ön yüz erişimini kesin olarak engeller.
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticationController extends Controller
{
public function login(Request $request)
{
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (!Auth::attempt($credentials)) {
return response()->json(['message' => 'Geçersiz kimlik bilgileri'], 401);
}
$user = Auth::user();
// Token oluştur (Sanctum veya bir JWT paketi kullanarak)
$token = $user->createToken('b2b-dashboard-access')->plainTextToken;
// Güvenli çerezi oluştur
$cookie = cookie(
name: 'saas_auth_token',
value: $token,
minutes: 1440, // 24 saat
path: "https://dev.to/",
domain: env('SESSION_DOMAIN'), // örn. '.smarttechdevs.in'
secure: true, // Üretim ortamında (HTTPS) kesinlikle true olmalıdır
httpOnly: true, // JavaScript/XSS erişimini engeller
sameSite: 'strict' // CSRF'yi engeller
);
return response()->json([
'status' => 'success',
'user' => [
'id' => $user->id,
'name' => $user->name,
'role' => $user->role
]
])->withCookie($cookie);
}
}
Adım 2: Frontend API Yapılandırması (Axios)
Çerezdeki token nedeniyle, frontend artık her istekte manuel olarak Authorization: Bearer başlığını eklemek zorunda değil. Axios’a, çerezleri API’ye yönelik çapraz köken isteklerinde otomatik olarak dahil etmesini söylemek yeterlidir.
// lib/api.js
import axios from 'axios';
const api = axios.create({
baseURL: process.env.NEXT_PUBLIC_API_URL,
// KRİTİK: Bu, HttpOnly çerezin her istekte gönderilmesini sağlar
withCredentials: true,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
export default api;
Sonuç
Tasarım aşamasında güvenlik, kurumsal mimarinin hobici projelerden ayrılmasını sağlar. JWT’lerinizi local storage’dan HttpOnly çerezlere taşıyarak, en yaygın ön yüz güvenlik açıklarının kapısını kapatmış olursunuz. API yönlendirmelerinizi ele alırken küçük bir değişiklik gerektirir, ancak bunun B2B müşterilerinize sağladığı huzur ve veri koruma çok değerlidir.
Kaynak: Orijinal Makale


