Next.js'te Özel Sayfa Koruma: Noindex Yetmez, Server Tarafında Kilitle
Linki bilenlerin görebileceği sayfalar ile gerçekten şifreli alanlar farklı şeylerdir. Next.js App Router'da noindex, middleware ve HttpOnly cookie ile pratik bir koruma modeli.
Next.js'te Özel Sayfa Koruma: Noindex Yetmez, Server Tarafında Kilitle#
noindex arama motorlarına bir ricadır, erişim kontrolü değildir. Bir sayfayı gerçekten gizlemek istiyorsan içerik HTML'e hiç girmemeli; şifre doğrulaması server tarafında yapılmalı ve yetki durumu güvenli bir cookie ile tutulmalıdır.
Bu ayrımı netleştirmek önemli: Linke sahip olan herkesin görebileceği "saklı" sayfa başka, yalnızca şifreyle açılacak özel not başka bir güvenlik modelidir.
Üç farklı seviye var#
| Seviye | Ne sağlar? | Ne sağlamaz? |
| --- | --- | --- |
| Menüden linklememek | Keşfedilebilirliği azaltır | URL bilen kişiyi engellemez |
| noindex ve sitemap dışı bırakmak | Arama sonuçlarına girmemeyi hedefler | Erişim kontrolü değildir |
| Server-side şifre kontrolü | İçeriği yetkisiz kullanıcıya render etmez | Güçlü parola ve rate limit ihtiyacını ortadan kaldırmaz |
Bir sayfa özel veri içeriyorsa üçüncü seviyeye çıkmak gerekir. Aksi halde metin client bundle içinde, HTML içinde veya cache katmanında kalabilir.
Middleware kapıyı erken kapatır#
Next.js middleware, route'a gelmeden önce karar vermek için iyi bir yerdir. Örneğin bir sayfanın opsiyonel secret query parametresiyle açılmasını istiyorsan:
import { NextRequest, NextResponse } from 'next/server' const privatePaths = new Set(['/about/naz']) export function middleware(request: NextRequest) { const secret = process.env.PAGE_SECRET if ( secret && privatePaths.has(request.nextUrl.pathname) && request.nextUrl.searchParams.get('key') !== secret ) { return new NextResponse(null, { status: 404 }) } return NextResponse.next() }
Bu model "linki bilen görsün ama key varsa daha da kapansın" gibi hafif gizlilik senaryoları için yeterli olabilir. Fakat şifreli not gibi içeriklerde form doğrulamasını ayrıca server action tarafına almak daha sağlıklıdır.
Server action ile şifreyi doğrula#
Client tarafında if (password === '...') yazmak güvenlik değildir. Şifre ve özel içerik server environment içinde durmalı, doğru girişten sonra HttpOnly cookie set edilmelidir.
'use server' import { cookies } from 'next/headers' import { redirect } from 'next/navigation' export async function unlockPrivateNote(formData: FormData) { const password = String(formData.get('password') || '') if (password !== process.env.PRIVATE_NOTE_PASSWORD) { redirect('/private-note?state=wrong') } cookies().set('private_note_access', 'signed-token', { httpOnly: true, sameSite: 'strict', secure: process.env.NODE_ENV === 'production', path: '/', maxAge: 60 * 60 * 24 * 7, }) redirect('/private-note') }
Üretimde token değerini düz string yapmak yerine HMAC ile imzalamak daha doğru olur. Böylece kullanıcı cookie değerini tahmin ederek yetki kazanamaz.
Özel metni client bundle'a koyma#
En kritik kural bu: Gizli metin React state'inde, client component içinde veya statik JSON dosyasında durmamalı. Sayfa kilitliyken özel metin response'a hiç girmemeli.
Doğru desen:
export default function PrivateNotePage() { const hasAccess = checkSignedCookie() if (!hasAccess) { return <PasswordForm /> } return <PrivateNote paragraphs={getNoteFromServerEnv()} /> }
Bu yaklaşımda şifre yoksa kullanıcı sadece formu görür. Özel metin HTML'de, hydration payload'ında veya JavaScript bundle'ında bulunmaz.
SEO tarafını da kapat#
Şifreli sayfaların indekslenmesini istemiyorsan üç noktayı birlikte kullan:
- Sayfa metadata'sında
robots: { index: false, follow: false } - Response header'da
X-Robots-Tag: noindex, nofollow robots.txtiçinde ilgili path'i disallow etmek
Bu üçlü erişim kontrolü değildir ama arama motorları ve crawler davranışı için iyi bir hijyen sağlar.
Kısa sonuç#
Gizli sayfa tasarlarken karar basit: İçeriğin başkası tarafından görülmesi sorun değilse link-only yeterli olabilir. İçerik gerçekten kişiselse server-side kontrol kullan. noindex görünürlüğü azaltır; şifreli server render ise içeriği gerçekten saklar.
Ne düşünüyorsun?
Tepki bırakarak geri bildirim ver