
Editing by Brayns AI
Kullanıcı oturumlarını yönetmek, modern web uygulamalarında hâlâ temel bir ihtiyaç. Özellikle stateless ve cookie tabanlı bir çözüm arıyorsanız, iron-session bu noktada sade, güvenli ve pratik bir seçenek sunar. Üstelik server-side rendering (SSR) ile de uyumlu çalışır. Bunun için ufak bir demo çalışması yaptım.
Geleneksel authentication kütüphaneleri (örneğin next-auth), OAuth gibi 3rd-party servislerle hızlı entegrasyon sağlar; ancak karmaşık yapılandırmaları, soyutlamaları ve sınırlı özelleştirme olanakları ile projeye esneklik katmak zor olabilir. Ayrıca auth.js gibi alternatiflerin belgeleri karmaşık olabilir ve yeni Next.js özellikleriyle (örneğin Server Actions) tam uyumlu çalışmayabilir.
Diğer yandan, Clerk gibi servis tabanlı çözümler; kullanıcı yönetimi, MFA, sosyal giriş gibi özellikleri kutudan çıktığı gibi sunsa da, hem ücretli bir yapıdadır hem de uygulamanızı onların altyapısına bağımlı hale getirir.
💭 Neden iron-session?
Eğer daha fazla kontrol, sade bir yapı ve hiçbir dış bağımlılık istemiyorsanız, iron-session cookie tabanlı, stateless ve TypeScript dostu yapısıyla öne çıkar.
- Cookie tabanlıdır, yani client'a JWT gibi token göndermek yerine, server-side session yönetimi sunar.
- Stateless yapıdadır, session bilgisi sadece cookie'de şifreli şekilde saklanır.
- TypeScript ile güçlü şekilde entegre olabilir.
Öncelikle kütüphaneyi kuralım:
npm install iron-session
iron-session ile kullanıcı oturumlarını yönetmek için ortak bir yapılandırma dosyasına ihtiyacımız var. Bu yapı, session verisinin cookie'ye nasıl yazılacağını ve şifrelemenin nasıl yapılacağını belirler.
lib/session.ts dosyasını oluşturalım:
import { cookies } from "next/headers"
import { getIronSession, IronSession } from "iron-session"
import type { SessionOptions } from "iron-session"
export type User = {
id?: number
username?: string
firstName?: string
token?: string
}
export const sessionOptions: SessionOptions = {
cookieName: "myapp_session",
password: process.env.SESSION_SECRET as string,
cookieOptions: {
secure: process.env.NODE_ENV === "production",
httpOnly: true,
sameSite: "lax",
},
}
export async function getSession(): Promise<IronSession<User>> {
const cookieStore = await cookies()
return await getIronSession<User>(cookieStore, sessionOptions)
}
iron-session ile çalışırken oturum bilgilerini şifrelemek için güçlü bir gizli anahtara (secret key) ihtiyacımız var. Bu gizli bilgi .env.local dosyasında saklanmalı ve en az 32 karakter uzunluğunda olmalıdır.
# .env.local
SESSION_SECRET=zkYEXAMPLEs3cretKey49281mkcxVXnalf0zq
Server Action ile Login: Gerçek API Üzerinden Oturum Yönetimi
Kullanıcının username ve password bilgileri formdan alınır ve Server Action üzerinden DummyJSON API'ye gönderilir. Başarılı giriş yapılırsa kullanıcıya ait veriler session içine kaydedilir.
✅ Teknik notlar:
- API başarılı dönerse, session içine kullanıcıya ait bilgiler (token, firstName, image…) şifrelenmiş cookie ile yazılıyor.
- Bu veri sadece sunucu tarafında okunabilir, client erişemez. Böylece güvenli bir yapı elde edilir.
// login.action.ts
"use server"
import { getSession } from "@/lib/session"
import { loginSchema } from "@/lib/validation"
import { z } from "zod"
export const loginAction = async (formData: z.infer<typeof loginSchema>) => {
const res = await fetch("https://dummyjson.com/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(formData),
})
if (!res.ok) {
const errorData = await res.json()
console.error("Login error from DummyJSON:", errorData)
return { success: false }
}
const data = await res.json()
const session = await getSession()
session.token = data.accessToken
session.firstName = data.firstName
await session.save()
return { success: true }
}
📄 Bu server action'ı tetikleyecek bir login formu; girişten sonra korumalı bir rotaya (/dashboard) yönlendirir:
"use client";
const LoginPage = () => {
// form (useForm), router (useRouter) ve error state tanımları kısaltıldı
const onSubmit = async (values: z.infer<typeof loginSchema>) => {
setError("");
try {
const response = await loginAction(values);
if (response.success) {
router.push("/dashboard");
}
} catch (err) {
setError("Something went wrong");
}
};
return (
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full space-y-6">
{/* username ve password alanları */}
</form>
);
};
export default LoginPage;
Kullanıcı giriş yaptıktan sonra /dashboard sayfasına yönlendirilir. Bu sayfa sadece geçerli oturuma sahip kullanıcılar tarafından erişilebilir. iron-session ile oturumu kontrol ederek yetkisiz erişimi engellemek oldukça kolay.
const DashboardPage = async () => {
const session = await getSession();
// Eğer token yoksa kullanıcı login sayfasına yönlendirilir
if (!session?.token) {
redirect("/login");
}
return (
<>
<h1>Merhaba, {session.firstName}</h1>
<form action={logoutAction}>
<Button type="submit">Logout</Button>
</form>
</>
);
};
export default DashboardPage;
🍪 Oturum Verileri Nerede Saklanıyor?
iron-session, oturum bilgilerini JWT gibi okunabilir bir token olarak değil, şifreli bir cookie içinde tarayıcıya yazar. Yani tüm session verileri tarayıcıda Application → Cookies sekmesinden görüntülenebilir.
Ancak önemli bir fark var:
- Cookie içinde ham veri değil, iron-session tarafından şifrelenmiş (encrypted) bir string saklanır. Bu sayede dışarıdan okunamaz veya değiştirilemez.
- Tarayıcıdaki bu veriyi doğrudan okuyamazsınız; sadece server, belirttiğiniz password yardımıyla bu veriyi çözebilir.
- Bu sayede client üzerinde veri tutuyor gibi görünse de, aslında tüm kontrol ve güvenlik server tarafındadır.

🔐 Oturumu Sonlandırma (logoutAction)
Kullanıcı oturumunu sonlandırmak için basit ama etkili bir server action fonksiyonu oluşturduk.
- Eğer bazı oturum bilgilerini korumak ama yalnızca token'ı sıfırlamak istiyorsanız,
session.token = undefinedgibi işlemler kullanılır. - Ancak tam bir logout işlemi için
destroy()her zaman daha güvenli ve temiz bir çözümdür.
"use server";
import { getSession } from "@/lib/session";
export const logoutAction = async () => {
const session = await getSession();
// session.token = undefined
session.destroy();
};
🔐 Access Token ve Refresh Token Yönetimi
Ufak değinmek istediğim bir nokta var: Access Token ve Refresh Token. Access Token, kullanıcıyı doğrulamak için kullanılır ve kısa ömürlüdür. Refresh Token ise, access token'ın süresi dolduğunda yeni bir token almak için kullanılır. iron-session, bu token'ları şifreli bir şekilde tarayıcıda saklayarak güvenliği artırır ve sunucu tarafında yönetilmesini sağlar. Böylece veri sızıntıları ve token çalınma riski azalır, sürekli giriş yapmaya gerek kalmaz.

Sonuç
iron-session ile güvenli ve basit bir şekilde kullanıcı oturumlarını yönetmek oldukça kolay. Bu yöntem, güvenliği artırırken uygulamanızın verimli bir şekilde çalışmasını sağlar. Kimlik doğrulama ve yetkilendirme süreçlerini optimize etmek için iron-session gibi çözümler, hızlı ve etkili bir yaklaşım sunar. Detaylarını GitHub repomda inceleyebilirsiniz.
Keyifli kodlamalar 👨💻 🎉
Bu yazı ilk olarak Medium'da yayınlandı.