Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce sisteminizde Node.js (tercihen LTS sürümü olan 22.x veya üzeri) ve bir paket yöneticisi (npm veya pnpm) yüklü olmalıdır. Ayrıca, OAuth2 sağlayıcısı olarak Google Cloud Console üzerinden bir "Client ID" ve "Client Secret" almanız gerekmektedir.
- Node.js 22.x veya üzeri sürüm.
- Express.js çatısı (web sunucusu için).
- Passport.js ve passport-google-oauth20 kütüphaneleri.
- Çevresel değişkenleri yönetmek için dotenv paketi.
Kurulumu yapmak için terminalinizde şu komutları çalıştırarak bağımlılıkları projenize dahil edin:
npm init -y
npm install express passport passport-google-oauth20 express-session dotenv
OAuth2 Akışının Mantığı ve Çalışma Prensibi
OAuth2, bir kullanıcının kimlik bilgilerini paylaşmadan, üçüncü taraf bir servisin sizin uygulamanıza erişim izni vermesini sağlayan bir yetkilendirme protokolüdür. Süreç, kullanıcının sağlayıcıya yönlendirilmesi, izin vermesi ve ardından sağlayıcının uygulamanıza bir "Access Token" göndermesiyle tamamlanır.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| OAuth2 (Passport.js) | Yüksek güvenlik, kolay entegrasyon | Harici servise bağımlılık |
| JWT (Kendi sisteminiz) | Tam kontrol | Şifre yönetimi sorumluluğu |
Adım Adım Yapılandırma: Passport.js Kurulumu
Passport.js, Node.js için esnek bir kimlik doğrulama kütüphanesidir. Strateji tabanlı çalışır; yani Google, Facebook veya Twitter için ayrı ayrı stratejiler tanımlayabilirsiniz. İlk adım olarak stratejiyi yapılandıralım.
require('dotenv').config();
const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/google/callback"
},
(accessToken, refreshToken, profile, cb) => {
// Burada kullanıcıyı veritabanınızda bulun veya oluşturun
return cb(null, profile);
}
));
Yukarıdaki kod, Google'dan gelen veriyi nasıl işleyeceğimizi belirler. cb (callback) fonksiyonu, kimlik doğrulama başarılı olduğunda çağrılır ve kullanıcı profilini Passport'a iletir.
Express.js ile Rotaların Tanımlanması
Kullanıcıyı Google giriş sayfasına yönlendirmek ve geri dönüşü karşılamak için iki ana rotaya ihtiyacımız vardır. Birinci rota, kullanıcının Google'a gitmesini sağlar; ikincisi ise Google'dan gelen veriyi işler.
const express = require('express');
const app = express();
app.get('/auth/google',
passport.authenticate('google', { scope: ['profile', 'email'] }));
app.get('/auth/google/callback',
passport.authenticate('google', { failureRedirect: '/login' }),
(req, res) => {
// Başarılı giriş sonrası yönlendirme
res.redirect('/dashboard');
});
Burada scope parametresi, Google'dan hangi verileri talep ettiğimizi belirtir. profile ve email en yaygın kullanılan kapsamlı izinlerdir.
Oturum Yönetimi ve Güvenlik Uyarıları
Kullanıcının giriş yaptıktan sonra sistemde kalıcı olması için oturum yönetimi (session) gereklidir. Express-session kullanarak bu süreci yönetebiliriz. Ancak, üretim ortamında (production) güvenlik için mutlaka secure: true ayarını kullanmalısınız.
Güvenlik Uyarısı: Üretim ortamında (production),
sessionayarlarında mutlakasecretanahtarınızı karmaşık bir string olarak belirleyin ve HTTPS protokolü kullanın. Aksi takdirde oturum çerezleri ele geçirilebilir.
const session = require('express-session');
app.use(session({
secret: 'cok-gizli-anahtar',
resave: false,
saveUninitialized: true,
cookie: { secure: false } // HTTPS varsa true yapın
}));
app.use(passport.initialize());
app.use(passport.session());
Yaygın Hatalar ve Debug İpuçları
OAuth2 entegrasyonunda en sık karşılaşılan hata "Redirect URI mismatch" hatasıdır. Bu hata, Google Cloud Console'da tanımladığınız yönlendirme adresi ile kodunuzdaki callbackURL değerinin uyuşmamasından kaynaklanır.
- Hata: 401 Unauthorized. Çözüm: Client ID veya Secret değerlerini kontrol edin.
- Hata: Callback URL hatası. Çözüm: Google Console'da tanımlı URL ile kodunuzdakini birebir eşitleyin.
- İpucu: Geliştirme aşamasında
DEBUG=passport*ortam değişkenini kullanarak Passport'un arka planda neler yaptığını loglayabilirsiniz.
Sorumluluk Reddi: Bu makale eğitim amaçlıdır. Yazılım güvenliği, uygulamanın bütünüyle ilgilidir. SQL injection, XSS ve CSRF gibi saldırılara karşı ek kütüphaneler (örneğin
helmet) kullanmayı ihmal etmeyin.
Sıkça Sorulan Sorular
OAuth2 ile gelen veriyi veritabanına nasıl kaydederim?
Passport stratejisi içindeki callback fonksiyonunda, profil bilgilerini kullanarak veritabanınızda bir sorgu yapmalı (örneğin: User.findOne({ googleId: profile.id })) ve kullanıcı yoksa oluşturmalısınız.
Neden Passport.js kullanmalıyım?
Çünkü Passport.js, onlarca farklı sağlayıcı için hazır stratejilere sahiptir ve kimlik doğrulama mantığını uygulamanızın geri kalanından izole ederek kodunuzu temiz tutar.
Token süresi dolduğunda ne olur?
OAuth2 protokolünde refresh token kullanarak yeni bir access token alabilirsiniz. Passport stratejisinde bu tokenları yönetmek için ek ayarlar yapmanız gerekebilir.
Kullanıcı girişi yaptıktan sonra nasıl korumalı rotalara erişirim?
Passport, req.isAuthenticated() metodunu sağlar. Bir middleware yazarak bu metodu kontrol edebilir ve giriş yapmamış kullanıcıları engelleyebilirsiniz.
HTTPS zorunlu mu?
Geliştirme ortamında (localhost) zorunlu değildir ancak kullanıcı verilerinin güvenliği için canlı ortamda (production) kesinlikle zorunludur.
OAuth2 Akışında İleri Düzey Hata Ayıklama ve Loglama Stratejileri
OAuth2 süreçlerinde karşılaşılan hatalar genellikle "callback" URL uyumsuzlukları, geçersiz "client secret" bilgileri veya eksik kapsam (scope) tanımlarından kaynaklanır. Uygulamanızın üretim ortamında sağlıklı çalışması için, Passport.js stratejisi içerisindeki hataları merkezi bir loglama mekanizmasıyla izlemeniz kritik öneme sahiptir.
Hata ayıklama sürecini kolaylaştırmak için debug paketini kullanabilir ve strateji içerisindeki hataları yakalayarak kullanıcıya anlamlı hata mesajları döndürebilirsiniz:
// passport.js stratejisi içerisinde hata yönetimi
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "/auth/google/callback"
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
if (err) {
console.error("Veritabanı hatası:", err);
return cb(err);
}
return cb(null, user);
});
}
));
OAuth2 Entegrasyonunda Performans Optimizasyonu
Her istekte veritabanına giderek kullanıcıyı doğrulamak, özellikle yüksek trafikli uygulamalarda performans darboğazına yol açabilir. Bu durumu aşmak için "Session Serialization" mekanizmasını optimize etmeli ve Redis gibi bir "in-memory" veri deposu kullanarak oturum bilgilerini önbelleğe almalısınız.
Redis kullanarak oturum yönetimi yapmak, uygulamanızın ölçeklenebilirliğini artırır. connect-redis kütüphanesini kullanarak Express oturumlarını Redis üzerinde tutabilirsiniz:
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const { createClient } = require('redis');
let redisClient = createClient({ legacyMode: true });
redisClient.connect().catch(console.error);
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: 'gizli-anahtar-buraya',
resave: false,
saveUninitialized: false,
cookie: { secure: true, maxAge: 60000 }
}));
Alternatif: Passport.js Yerine Doğrudan OAuth2 Kütüphaneleri
Bazı durumlarda, Passport.js'in sunduğu soyutlama katmanı yerine, daha düşük seviyeli ve esnek bir yapıya ihtiyaç duyabilirsiniz. simple-oauth2 kütüphanesi, özellikle API tabanlı servisler arası iletişimde veya Passport'un karmaşık yapısına girmek istemediğiniz durumlarda mükemmel bir alternatiftir.
simple-oauth2 ile manuel bir "Authorization Code" akışı şu şekilde başlatılabilir:
const { AuthorizationCode } = require('simple-oauth2');
const config = {
client: {
id: 'CLIENT_ID',
secret: 'CLIENT_SECRET'
},
auth: {
tokenHost: 'https://oauth.provider.com'
}
};
const client = new AuthorizationCode(config);
// Yetkilendirme URL'sini oluşturma
const authorizationUri = client.authorizeURL({
redirect_uri: 'http://localhost:3000/callback',
scope: 'profile email'
});
console.log('Kullanıcıyı şu adrese yönlendirin:', authorizationUri);
Bu yaklaşım, özellikle mikro hizmet mimarilerinde her servisin kendi kimlik doğrulama mantığını yönetmesi gerektiğinde daha fazla kontrol sağlar.
Sonuç
Node.js ile OAuth2 entegrasyonu, başlangıçta karmaşık görünse de Passport.js gibi güçlü araçlarla oldukça yönetilebilir bir süreçtir. Bu rehberde, bir uygulamanın temel kimlik doğrulama akışını nasıl kuracağınızı, oturumları nasıl yöneteceğinizi ve güvenlik önlemlerini nasıl alacağınızı öğrendiniz. Bir sonraki adım olarak, JWT (JSON Web Token) kullanarak API tabanlı kimlik doğrulama sistemlerini araştırmanızı ve uygulamanızı daha ölçeklenebilir hale getirmenizi öneririm.


Yorumlar (0)
Yorum Yaz