Mobil, Web ve API için Kimlik Doğrulama Sağlayıcıları: Doğru Çözümü Seçmek için Eksiksiz Kılavuz
Auth0, Firebase Auth, Supabase Auth, AWS Cognito ve özel çözümlerin gerçek dünya karşılaştırması. Her birini ne zaman kullanmalı, maliyet analizi ve bana her şeyi öğreten hata ayıklama kabusları.
Geçen yıl, platformumuz genelinde bir kimlik doğrulama sistemleri karmaşası devraldım. Web uygulaması için Auth0, mobil için Firebase Auth, API'ler için özel JWT çözümü ve üç farklı kullanıcı veritabanımız vardı. Bir kullanıcı web'de kaydolduktan sonra mobil'den hesabına erişmeye çalıştığında "kullanıcı bulunamadı" hatası aldı. İşte o zaman piyasadaki her kimlik doğrulama sağlayıcısını denetlemeye ve kimlik doğrulama stratejimizi birleştirmeye karar verdim.
15'ten fazla üretim uygulaması için kimlik doğrulama çözümleri uyguladıktan ve sabah 3'te kabul etmek istemediğimden daha fazla kez kimlik doğrulama sorunlarını hata ayıkladıktan sonra, farklı senaryolar için doğru kimlik doğrulama sağlayıcısını seçme konusunda öğrendiklerim burada.
Kimlik Doğrulama Manzarası: Üretimde Gerçekten İşe Yarayan#
Acımasız gerçekle başlayayım: mükemmel bir kimlik doğrulama sağlayıcısı yok. Her birinin, 100.000+ kullanıcı ve uyumluluk gereksinimleriyle uğraşırken acı verici bir şekilde belirgin hale gelen tavizleri var. İşte gerçek üretim ortamlarında kullandıklarım:
Auth0: Kurumsal İş Atı#
Ne zaman kullanırım: Kurumsal uygulamalar, B2B SaaS, uyumluluk ağırlıklı endüstriler Ne zaman kaçınırım: Sıkı bütçeli startup'lar, basit tüketici uygulamaları
Gerçek üretim deneyimi:
// Üretimde gerçekten çalışan Auth0 yapılandırması
const auth0Config = {
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
audience: process.env.AUTH0_AUDIENCE,
// Kritik: API erişimi için uygun scope'ları ayarlayın
scope: 'openid profile email read:users write:users',
// Rate limit'lerden kaçınmak için token'ları düzgün önbelleğe alın
cacheLocation: 'localstorage',
useRefreshTokens: true,
// Token süresinin dolmasını zarif bir şekilde ele alın
onRedirectCallback: (appState) => {
window.history.replaceState(
{},
document.title,
appState?.returnTo || window.location.pathname
);
}
};
İyi yanları:
- SOC 2, GDPR, HIPAA uyumluluğu hazır
- Mükemmel kurumsal özellikler (SAML, LDAP, MFA)
- Kullanıcı yönetimi için sağlam admin paneli
- Harika dokümantasyon ve destek
Kötü yanları:
- Maliyet: 7.000 kullanıcı için 23$/ay, sonra kullanıcı başına 0,00325$. 100k kullanıcıda, bu 300$/ay'dan fazla
- Karmaşıklık: Basit uygulamalar için aşırı
- Satıcı kilitlenmesi: Özel kurallar ve hook'lar sizi Auth0'a bağlar
- Performans: Yüksek trafikli senaryolarda bazen yavaş token doğrulama
Gerçek hata ayıklama hikayesi: Auth0'ın yoğun saatlerde token'ları doğrulamak için 2+ saniye sürdüğü bir üretim sorunumuz vardı. Token'ları düzgün önbelleğe almadığımız için rate limit'lere çarptığımız ortaya çıktı. Çözüm Redis tabanlı token önbellekleme uygulamaktı, ancak bu yığınımıza başka bir bağımlılık ekledi.
Firebase Auth: Google Ekosistem Seçimi#
Ne zaman kullanırım: Mobil öncelikli uygulamalar, Google ekosistem entegrasyonu, hızlı prototipleme Ne zaman kaçınırım: Çok kiracılı B2B uygulamaları, katı uyumluluk gereksinimleri
Üretim yapılandırması:
// React Native + Web için Firebase Auth kurulumu
import { initializeApp } from 'firebase/app';
import { getAuth, connectAuthEmulator } from 'firebase/auth';
const firebaseConfig = {
apiKey: process.env.FIREBASE_API_KEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
projectId: process.env.FIREBASE_PROJECT_ID,
// Kritik: Bunları istemci tarafı kodda açığa çıkarmayın
storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID
};
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);
// Üretime hazır hata işleme
auth.onAuthStateChanged((user) => {
if (user) {
// Token'ı her zaman sunucu tarafında doğrulayın
user.getIdToken(true).then((token) => {
// Doğrulama için backend'inize gönderin
verifyTokenOnServer(token);
});
}
});
İyi yanları:
- Ücretsiz katman: Ayda 10.000 kimlik doğrulama ücretsiz
- Mobil entegrasyonu: Mükemmel React Native desteği
- Google hizmetleri: Firestore, Functions ile sorunsuz entegrasyon
- Basit kurulum: 30 dakikada auth'u çalıştırabilirsiniz
Kötü yanları:
- Google kilitlenmesi: Google ekosisteminden göç etmek zor
- Sınırlı özelleştirme: Auth akışlarını Auth0 kadar özelleştiremezsiniz
- Admin sınırlamaları: Auth0'a kıyasla temel admin paneli
- Uyumluluk: Sınırlı kurumsal uyumluluk özellikleri
Gerçek maliyet analizi: 50k aylık aktif kullanıcısı olan bir mobil uygulama için, Firebase Auth 0$ maliyetindeyken Auth0 ayda 150$. Ancak Firestore kullanımını ve diğer Google hizmetlerini hesaba kattığınızda, toplam maliyet farkı önemli ölçüde azalır.
Supabase Auth: Açık Kaynak Alternatifi#
Ne zaman kullanırım: Açık kaynak projeler, PostgreSQL ağırlıklı yığınlar, maliyet bilinçli startup'lar Ne zaman kaçınırım: Kurumsal uyumluluk gereksinimleri, karmaşık çok kiracılı senaryolar
Üretim kurulumu:
// Uygun hata işleme ile Supabase Auth
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!
);
// Üretime hazır auth hook'ları
export const useAuth = () => {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
// İlk oturumu al
supabase.auth.getSession().then(({ data: { session } }) => {
setUser(session?.user ?? null);
setLoading(false);
});
// Auth değişikliklerini dinle
const { data: { subscription } } = supabase.auth.onAuthStateChange(
async (event, session) => {
setUser(session?.user ?? null);
setLoading(false);
}
);
return () => subscription.unsubscribe();
}, []);
return { user, loading };
};
İyi yanları:
- Maliyet: Sınırsız kullanıcı için 25$/ay (kullanım limitleriyle)
- Açık kaynak: Gerekirse kendi sunucunuzda barındırabilirsiniz
- PostgreSQL: Özel sorgular için doğrudan veritabanı erişimi
- Gerçek zamanlı: Yerleşik gerçek zamanlı abonelikler
Kötü yanları:
- Olgunluk: Auth0/Firebase'den daha az olgun
- Kurumsal özellikler: Sınırlı kurumsal uyumluluk özellikleri
- Destek: Kurumsal destek yerine topluluk desteği
- Karmaşıklık: Gelişmiş özellikler için daha fazla kurulum gerektirir
Gerçek uygulama hikayesi: Bir startup projesi için Supabase kullandık ve ücretsiz katman limitlerini hızla aştık. Ücretli katmana geçiş sorunsuzdı, ancak ihtiyacımız olan bazı gelişmiş özelliklerin (özel claim'ler gibi) beklenenden daha fazla çalışma gerektirdiğini keşfettik.
AWS Cognito: AWS Native Çözümü#
Ne zaman kullanırım: AWS ağırlıklı mimariler, serverless uygulamalar, maliyet optimizasyonu Ne zaman kaçınırım: AWS dışı ortamlar, hızlı prototipleme
Üretim yapılandırması:
// CDK ile AWS Cognito
import { UserPool, UserPoolClient, AccountRecovery } from 'aws-cdk-lib/aws-cognito';
import { Duration } from 'aws-cdk-lib';
const userPool = new UserPool(this, 'MyUserPool', {
userPoolName: 'my-app-users',
selfSignUpEnabled: true,
signInAliases: {
email: true,
phone: true,
},
standardAttributes: {
email: {
required: true,
mutable: true,
},
},
passwordPolicy: {
minLength: 8,
requireLowercase: true,
requireUppercase: true,
requireDigits: true,
requireSymbols: true,
},
accountRecovery: AccountRecovery.EMAIL_ONLY,
// Üretim için kritik: MFA'yı etkinleştir
mfa: Mfa.REQUIRED,
mfaSecondFactor: {
sms: true,
otp: true,
},
// Token yapılandırması
accessTokenValidity: Duration.hours(1),
idTokenValidity: Duration.hours(1),
refreshTokenValidity: Duration.days(30),
});
İyi yanları:
- Maliyet: Yüksek hacimli uygulamalar için çok ucuz
- AWS entegrasyonu: Lambda, API Gateway vb. ile sorunsuz
- Ölçeklenebilirlik: Milyonlarca kullanıcıyı yönetir
- Güvenlik: AWS düzeyinde güvenlik ve uyumluluk
Kötü yanları:
- Karmaşıklık: Dik öğrenme eğrisi
- AWS kilitlenmesi: AWS ekosistemi dışında kullanmak zor
- UI: Temel barındırılan UI, özel geliştirme gerektirir
- Hata ayıklama: AWS CloudWatch logları bunaltıcı olabilir
Gerçek maliyet karşılaştırması: 100k kullanıcı için, Cognito ~50$/ay maliyetindeyken Auth0 300$/ay'dan fazla. Ancak geliştirme süresi ve AWS uzmanlık gereksinimleri bu tasarrufları dengeleyebilir.
Özel JWT Çözümü: Tam Kontrol Seçeneği#
Ne zaman kullanırım: Basit uygulamalar, öğrenme projeleri, tam kontrole ihtiyacınız olduğunda Ne zaman kaçınırım: Üretim uygulamaları, uyumluluk gereksinimleri, takım projeleri
Üretim uygulaması:
// Uygun güvenlikle özel JWT auth
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import { randomBytes } from 'crypto';
class CustomAuthService {
private readonly JWT_SECRET = process.env.JWT_SECRET!;
private readonly JWT_EXPIRES_IN = '1h';
private readonly REFRESH_TOKEN_EXPIRES_IN = '7d';
async generateTokens(userId: string, email: string) {
const accessToken = jwt.sign(
{ userId, email, type: 'access' },
this.JWT_SECRET,
{ expiresIn: this.JWT_EXPIRES_IN }
);
const refreshToken = jwt.sign(
{ userId, type: 'refresh' },
this.JWT_SECRET,
{ expiresIn: this.REFRESH_TOKEN_EXPIRES_IN }
);
// Refresh token hash'ini veritabanında sakla
const refreshTokenHash = await bcrypt.hash(refreshToken, 12);
await this.storeRefreshToken(userId, refreshTokenHash);
return { accessToken, refreshToken };
}
async verifyToken(token: string) {
try {
const decoded = jwt.verify(token, this.JWT_SECRET) as any;
// Token'ın kara listelenip listelenmediğini kontrol et
const isBlacklisted = await this.isTokenBlacklisted(token);
if (isBlacklisted) {
throw new Error('Token kara listede');
}
return decoded;
} catch (error) {
throw new Error('Geçersiz token');
}
}
async refreshAccessToken(refreshToken: string) {
try {
const decoded = jwt.verify(refreshToken, this.JWT_SECRET) as any;
// Refresh token'ın veritabanında var olduğunu doğrula
const isValid = await this.verifyRefreshToken(decoded.userId, refreshToken);
if (!isValid) {
throw new Error('Geçersiz refresh token');
}
// Yeni access token oluştur
const user = await this.getUserById(decoded.userId);
return this.generateTokens(user.id, user.email);
} catch (error) {
throw new Error('Geçersiz refresh token');
}
}
}
İyi yanları:
- Tam kontrol: Auth akışlarının tam özelleştirmesi
- Maliyet: Sadece altyapı maliyetleri
- Öğrenme: Auth kavramlarını anlamak için harika
- Esneklik: Herhangi bir auth pattern'ini uygulayabilirsiniz
Kötü yanları:
- Güvenlik riskleri: Güvenlik hataları yapmak kolay
- Bakım: Her şeyden siz sorumlusunuz
- Uyumluluk: Yerleşik uyumluluk özellikleri yok
- Zaman yatırımı: Önemli geliştirme süresi gerekli
Detaylı Karşılaştırma Matrisi#
Özellik | Auth0 | Firebase Auth | Supabase Auth | AWS Cognito | Özel JWT |
---|---|---|---|---|---|
Kurulum Süresi | 2-4 saat | 30 dakika | 1-2 saat | 4-8 saat | 1-2 hafta |
Maliyet (100k kullanıcı) | 300$/ay+ | 0-50$/ay | 25$/ay | 50$/ay | 10$/ay |
Mobil Desteği | Mükemmel | Mükemmel | İyi | İyi | Manuel |
Web Desteği | Mükemmel | İyi | Mükemmel | Temel | Manuel |
API Desteği | Mükemmel | İyi | İyi | Mükemmel | Manuel |
Kurumsal Özellikler | Mükemmel | Temel | Sınırlı | İyi | Manuel |
Uyumluluk | SOC2, GDPR, HIPAA | Temel | Sınırlı | SOC2, GDPR | Manuel |
Özelleştirme | Yüksek | Orta | Yüksek | Orta | Sınırsız |
Satıcı Kilitlenmesi | Yüksek | Yüksek | Orta | Yüksek | Yok |
Öğrenme Eğrisi | Orta | Düşük | Orta | Yüksek | Yüksek |
Gerçek Dünya Senaryoları: Her Birini Ne Zaman Kullanmalı#
Senaryo 1: Kurumsal Müşterilerle B2B SaaS#
Gereksinimler: SAML/SSO, uyumluluk, kullanıcı yönetimi, denetim logları Seçim: Auth0 Neden: Kurumsal özellikler, hazır uyumluluk, mükemmel admin paneli
Gerçek uygulama:
// Auth0 kurumsal yapılandırması
const auth0Config = {
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
audience: process.env.AUTH0_AUDIENCE,
// Kurumsal özellikler
scope: 'openid profile email read:users write:users read:logs',
// SAML yapılandırması
samlConfiguration: {
signInUrl: process.env.SAML_SIGN_IN_URL,
signOutUrl: process.env.SAML_SIGN_OUT_URL,
},
// Kurumsal mantık için özel kurallar
rules: [
{
name: 'Kurumsal metadata ekle',
script: `
function (user, context, callback) {
// Kurumsal özel claim'ler ekle
context.idToken['https://myapp.com/enterprise'] = user.app_metadata.enterprise;
callback(null, user, context);
}
`
}
]
};
Senaryo 2: Mobil Öncelikli Tüketici Uygulaması#
Gereksinimler: Sosyal giriş, push bildirimleri, hızlı geliştirme Seçim: Firebase Auth Neden: Mükemmel mobil entegrasyon, ücretsiz katman, Google ekosistemi
Gerçek uygulama:
// Sosyal giriş ile Firebase Auth
import {
signInWithPopup,
GoogleAuthProvider,
FacebookAuthProvider
} from 'firebase/auth';
const googleProvider = new GoogleAuthProvider();
const facebookProvider = new FacebookAuthProvider();
// Sağlayıcıları yapılandır
googleProvider.addScope('email');
googleProvider.addScope('profile');
facebookProvider.addScope('email');
// Sosyal giriş uygulaması
const signInWithGoogle = async () => {
try {
const result = await signInWithPopup(auth, googleProvider);
const user = result.user;
// Token'ı doğrulama için backend'e gönder
const token = await user.getIdToken();
await verifyTokenOnBackend(token);
return user;
} catch (error) {
console.error('Google giriş hatası:', error);
throw error;
}
};
Senaryo 3: Maliyet Bilinçli Startup#
Gereksinimler: Düşük maliyet, PostgreSQL entegrasyonu, hızlı iterasyon Seçim: Supabase Auth Neden: 25$/ay'a sınırsız kullanıcı, doğrudan veritabanı erişimi
Gerçek uygulama:
// Özel kullanıcı metadata'sı ile Supabase Auth
const { data: { user }, error } = await supabase.auth.signUp({
email: 'user@example.com',
password: 'securepassword',
options: {
data: {
full_name: 'John Doe',
company: 'Startup Inc',
role: 'admin'
}
}
});
// Özel mantık için doğrudan veritabanı sorguları
const { data: users, error } = await supabase
.from('users')
.select('*')
.eq('company_id', companyId)
.order('created_at', { ascending: false });
Senaryo 4: AWS Ağırlıklı Mimari#
Gereksinimler: Serverless, maliyet optimizasyonu, AWS entegrasyonu Seçim: AWS Cognito Neden: Sorunsuz Lambda entegrasyonu, ölçekte çok düşük maliyet
Gerçek uygulama:
// Lambda trigger'ları ile Cognito
import { CognitoJwtVerifier } from 'aws-jwt-verify';
const verifier = CognitoJwtVerifier.create({
userPoolId: process.env.COGNITO_USER_POOL_ID,
tokenUse: 'access',
clientId: process.env.COGNITO_CLIENT_ID,
});
// Cognito auth ile Lambda fonksiyonu
export const handler = async (event) => {
try {
const token = event.headers.Authorization?.replace('Bearer ', '');
const payload = await verifier.verify(token);
// Kullanıcı kimliği doğrulandı, iş mantığı ile devam et
const userId = payload.sub;
const result = await processUserRequest(userId, event.body);
return {
statusCode: 200,
body: JSON.stringify(result)
};
} catch (error) {
return {
statusCode: 401,
body: JSON.stringify({ error: 'Yetkisiz' })
};
}
};
Senaryo 5: Öğrenme Projesi veya Basit Uygulama#
Gereksinimler: Auth kavramlarını anlama, tam kontrol Seçim: Özel JWT Çözümü Neden: Eğitim değeri, satıcı bağımlılığı yok
Maliyet Analizi: Üretimden Gerçek Rakamlar#
Üretimde gördüğüm gerçek maliyetleri açıklayayım:
Auth0 Maliyet Dağılımı#
- Ücretsiz katman: 7.000 kullanıcı
- Büyüme planı: 23$/ay + kullanıcı başına 0,00325$
- Kurumsal plan: Özel fiyatlandırma
- Gerçek örnek: 50k kullanıcı = 23$ + (43k × 0,00325$) = 162,75$/ay
Firebase Auth Maliyet Dağılımı#
- Ücretsiz katman: Ayda 10.000 kimlik doğrulama
- Ücretli katman: Ücretsiz katmandan sonra kimlik doğrulama başına 0,01$
- Gerçek örnek: Ayda 50k kimlik doğrulama = 0$ (ücretsiz katman içinde)
Supabase Auth Maliyet Dağılımı#
- Ücretsiz katman: 50.000 kullanıcı
- Pro plan: Sınırsız kullanıcı için 25$/ay
- Gerçek örnek: 100k kullanıcı = 25$/ay
AWS Cognito Maliyet Dağılımı#
- Kullanıcı havuzları: MAU başına 0,0055$
- Kimlik havuzları: MAU başına 0,0055$
- Gerçek örnek: 50k MAU = 275$/ay
Migrasyon Stratejileri: Gerçek Migrasyonlardan Dersler#
Auth sağlayıcıları arasında birçok kez geçiş yaptım. İşte gerçekten işe yarayan stratejiler:
Özel JWT'den Auth0'a Migrasyon#
// Kullanıcı verisi için migrasyon script'i
const migrateUsersToAuth0 = async () => {
const users = await getUsersFromCustomDB();
for (const user of users) {
try {
// Auth0'da kullanıcı oluştur
const auth0User = await auth0Management.users.create({
email: user.email,
password: generateTemporaryPassword(),
email_verified: user.emailVerified,
user_metadata: {
migrated_from: 'custom_jwt',
original_user_id: user.id
}
});
// Yerel veritabanını Auth0 kullanıcı ID'si ile güncelle
await updateUserAuth0Id(user.id, auth0User.user_id);
console.log(`Kullanıcı taşındı: ${user.email}`);
} catch (error) {
console.error(`${user.email} kullanıcısını taşıma başarısız:`, error);
}
}
};
Firebase'den Auth0'a Migrasyon#
// Firebase'den Auth0'a migrasyon
const migrateFromFirebase = async () => {
const firebaseUsers = await getFirebaseUsers();
for (const firebaseUser of firebaseUsers) {
try {
// Auth0'da kullanıcı oluştur
const auth0User = await auth0Management.users.create({
email: firebaseUser.email,
email_verified: firebaseUser.emailVerified,
user_metadata: {
firebase_uid: firebaseUser.uid,
migrated_at: new Date().toISOString()
}
});
// Özel claim'leri taşı
if (firebaseUser.customClaims) {
await auth0Management.users.update(
{ user_id: auth0User.user_id },
{ app_metadata: firebaseUser.customClaims }
);
}
} catch (error) {
console.error(`${firebaseUser.email} için migrasyon başarısız:`, error);
}
}
};
Güvenlik Hususları: Zor Yoldan Öğrendiklerim#
Token Güvenliği#
// Güvenli token işleme
const secureTokenStorage = {
// Token'ları güvenli sakla
storeTokens: (accessToken: string, refreshToken: string) => {
// Güvenli depolama kullan (hassas veriler için localStorage değil)
if (isMobile()) {
// Keychain (iOS) veya Keystore (Android) kullan
SecureStore.setItemAsync('access_token', accessToken);
SecureStore.setItemAsync('refresh_token', refreshToken);
} else {
// Web için httpOnly çerezler kullan
document.cookie = `access_token=${accessToken}; HttpOnly; Secure; SameSite=Strict`;
}
},
// Token'ları düzenli olarak döndür
rotateTokens: async () => {
const refreshToken = await getRefreshToken();
const response = await fetch('/api/auth/refresh', {
method: 'POST',
headers: { 'Authorization': `Bearer ${refreshToken}` }
});
if (response.ok) {
const { accessToken, refreshToken: newRefreshToken } = await response.json();
secureTokenStorage.storeTokens(accessToken, newRefreshToken);
}
}
};
Rate Limiting#
// Auth endpoint'leri için rate limiting
const rateLimit = require('express-rate-limit');
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 dakika
max: 5, // Pencere başına 5 deneme
message: 'Çok fazla kimlik doğrulama denemesi, lütfen daha sonra tekrar deneyin',
standardHeaders: true,
legacyHeaders: false,
// Dağıtık sistemler için rate limit verisini Redis'te sakla
store: new RedisStore({
client: redisClient,
prefix: 'auth_rate_limit:'
})
});
app.use('/api/auth/login', authLimiter);
app.use('/api/auth/register', authLimiter);
Performans Optimizasyonu: Yüksek Trafikli Uygulamalardan Dersler#
Token Önbellekleme#
// Redis tabanlı token önbellekleme
class TokenCache {
private redis: Redis;
private readonly CACHE_TTL = 3600; // 1 saat
constructor() {
this.redis = new Redis(process.env.REDIS_URL);
}
async cacheToken(userId: string, token: string): Promise<void> {
await this.redis.setex(`token:${userId}`, this.CACHE_TTL, token);
}
async getCachedToken(userId: string): Promise<string | null> {
return await this.redis.get(`token:${userId}`);
}
async invalidateToken(userId: string): Promise<void> {
await this.redis.del(`token:${userId}`);
}
}
Bağlantı Havuzu#
// Auth için veritabanı bağlantı havuzu
const pool = new Pool({
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
// Auth sorguları için optimize et
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
// Üretim için SSL'i etkinleştir
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
});
Kimlik Doğrulama Sorunlarını Hata Ayıklama: Gerçek Hikayeler#
Kaybolan Kullanıcılar Vakası#
Sorun: Kullanıcılar Auth0'da oluşturuluyordu ancak veritabanımızda görünmüyordu Kök neden: Auth0 webhook'u ile kullanıcı oluşturma arasında yarış durumu Çözüm: Uygun hata işleme ile idempotent kullanıcı oluşturma uygulandı
// Idempotent kullanıcı oluşturma
const createUserIfNotExists = async (auth0User: any) => {
const existingUser = await db.user.findUnique({
where: { auth0Id: auth0User.user_id }
});
if (existingUser) {
return existingUser;
}
try {
return await db.user.create({
data: {
auth0Id: auth0User.user_id,
email: auth0User.email,
emailVerified: auth0User.email_verified,
metadata: auth0User.user_metadata
}
});
} catch (error) {
// Yarış durumunu ele al
if (error.code === 'P2002') {
return await db.user.findUnique({
where: { auth0Id: auth0User.user_id }
});
}
throw error;
}
};
Token Doğrulama Gizemi#
Sorun: API çağrıları aralıklı olarak "geçersiz token" hatalarıyla başarısız oluyordu Kök neden: Sunucular ve Auth0 arasında saat kayması Çözüm: Saat kayması toleransı ile token doğrulama uygulandı
// Saat kayması toleransı ile token doğrulama
const validateToken = async (token: string) => {
try {
const decoded = jwt.verify(token, process.env.AUTH0_PUBLIC_KEY, {
algorithms: ['RS256'],
clockTolerance: 30, // 30 saniye tolerans
issuer: `https://${process.env.AUTH0_DOMAIN}/`,
audience: process.env.AUTH0_AUDIENCE
});
return decoded;
} catch (error) {
console.error('Token doğrulama hatası:', error);
throw new Error('Geçersiz token');
}
};
Son Öneriler: Farklı Ne Yapardım#
Yeni Projeler İçin#
- Mobil öncelikli tüketici uygulaması oluşturuyorsanız Firebase Auth ile başlayın
- Maliyet bilinçliyseniz ve PostgreSQL ağırlıklıysanız Supabase Auth kullanın
- İlk günden kurumsal özelliklere ihtiyacınız varsa Auth0'a gidin
- AWS'ye zaten yoğun yatırım yaptıysanız AWS Cognito'yu seçin
Mevcut Projeler İçin#
- Gerekli olmadıkça geçiş yapmayın - auth migrasyonları acı vericidir
- Değişiklik yapmadan önce uygun izleme uygulayın
- İkili auth sistemleriyle kademeli geçiş planlayın
- Kapsamlı test yapın - auth hataları en kötü hata türüdür
Maliyet Optimizasyon Stratejileri#
- Kullanım kalıplarını izleyin ve buna göre optimize edin
- Auth sağlayıcı çağrılarını azaltmak için uygun önbellekleme uygulayın
- Token oluşturmayı minimize etmek için refresh token'ları kullanın
- Farklı kullanıcı segmentleri için hibrit yaklaşımları düşünün
Güvenlik En İyi Uygulamaları#
- Token'ları her zaman sunucu tarafında doğrulayın - istemci tarafı doğrulamaya asla güvenmeyin
- Güvenli token depolama ile uygun oturum yönetimi uygulayın
- Her yerde HTTPS kullanın - özellikle auth endpoint'leri için
- Auth uygulamanızın düzenli güvenlik denetimleri
- Şüpheli aktiviteyi izleyin ve rate limiting uygulayın
Performans Optimizasyon İpuçları#
- Veritabanı sorgularını azaltmak için kullanıcı oturumlarını önbelleğe alın
- Veritabanı bağlantıları için bağlantı havuzu kullanın
- Auth sağlayıcı API çağrılarını azaltmak için token önbellekleme uygulayın
- Uygun algoritmalar ve önbellekleme ile token doğrulamayı optimize edin
- Auth performansını izleyin ve darboğazları optimize edin
Takım Hususları#
- Takım uzmanlığına göre seçin - kimse AWS bilmiyorsa Cognito'yu seçmeyin
- Bakım yükünü düşünün - özel çözümler sürekli çalışma gerektirir
- Takım büyümesini planlayın - auth sistemleri takımınızla ölçeklenmeli
- Her şeyi belgeleyin - auth kritik altyapıdır
- Yedek planınız olsun - gerektiğinde nasıl geçiş yapacağınızı her zaman bilin
Sonuç#
Doğru auth sağlayıcısını seçmek, "en iyi" çözümü bulmaktan çok özel gereksinimlerinizi anlamakla ilgilidir. Her sağlayıcının güçlü ve zayıf yönleri vardır ve doğru seçim takımınızın uzmanlığına, bütçenize, uyumluluk gereksinimlerinize ve teknik kısıtlamalarınıza bağlıdır.
Öğrendiğim en önemli ders, basit başlamak ve uygulamanız büyüdükçe auth stratejinizi geliştirmektir. İlk günden kimlik doğrulamayı aşırı mühendislik yapmayın, ancak seçiminizin güvenlik ve ölçeklenebilirlik etkilerini de göz ardı etmeyin.
Unutmayın: kimlik doğrulama sadece güvenlikle ilgili değildir - kullanıcı deneyimi, geliştirici deneyimi ve iş gereksinimleriyle ilgilidir. Akıllıca seçin, dikkatli uygulayın ve her zaman bir yedek planınız olsun.
Yorumlar (0)
Sohbete katıl
Düşüncelerini paylaşmak ve toplulukla etkileşim kurmak için giriş yap
Henüz yorum yok
Bu yazı hakkında ilk düşüncelerini paylaşan sen ol!
Yorumlar (0)
Sohbete katıl
Düşüncelerini paylaşmak ve toplulukla etkileşim kurmak için giriş yap
Henüz yorum yok
Bu yazı hakkında ilk düşüncelerini paylaşan sen ol!