R 1
Roksam
Test5410 1
Test5410
Hikaye Ekle

[NODE JS] Environment Variables ile Gizli Bilgi Yönetimi

  • Konuyu başlatan Konuyu başlatan Silverhand
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 1
  • Görüntüleme Görüntüleme 13
nodejs.png


[NODE JS] Environment Variables ile Gizli Bilgi Yönetimi​


Selamlar, bu konuda environment variable yani çevre değişkenleri ile hassas bilgilerin yönetimini anlatacağım. Veritabanı şifreleri, API key'leri, JWT secret'ları gibi gizli bilgileri koda yazmak en büyük güvenlik hatalarından biridir. Bu bilgileri environment variable olarak yönetmeniz gerekir.

Neden bu kadar önemli? Çünkü kodunuz Git'e commit edilir, GitHub'a push edilir. Eğer şifreniz kodun içindeyse tüm dünya görebilir. GitHub'da bot'lar sürekli yeni push edilen kodları tarayıp API key ve şifre arıyor. AWS key'iniz 5 dakika bile açıkta kalsa binlerce dolarlık cryptocurrency mining yapılabilir hesabınızdan. Abartmıyorum, gerçekten yaşanan bir şey bu.

Ben bir keresinde Junior bir arkadaşın MongoDB Atlas şifresini .env yerine doğrudan koda yazdığını ve commit ettiğini gördüm. Neyse ki public repo değildi ama yine de hemen şifreyi değiştirdik ve git history'den temizledik. O günden sonra takımda pre-commit hook koyduk, secret pattern'ı yakalayıp commit'i engelliyor.

Node.js'te process.env objesi üzerinden environment variable'lara erişebilirsiniz. İşletim sistemi seviyesinde tanımlı olan tüm değişkenler burada bulunur. Ama her seferinde terminal'de export yazmak yerine .env dosyası kullanmak çok daha pratik.

process.env Kullanımı​


JavaScript:
// Environment variable'lara erisim
console.log(process.env.NODE_ENV);   // development, production, test
console.log(process.env.PORT);       // 3000
console.log(process.env.DB_HOST);    // localhost

// Varsayilan deger ile kullanim
const port = process.env.PORT || 3000;
const dbHost = process.env.DB_HOST || 'localhost';
const dbPort = parseInt(process.env.DB_PORT || '5432', 10);
const debugMode = process.env.DEBUG === 'true'; // String'den boolean'a

// Config objesi olusturma
const config = {
    app: {
        port: parseInt(process.env.PORT || '3000', 10),
        env: process.env.NODE_ENV || 'development',
        isProduction: process.env.NODE_ENV === 'production'
    },
    db: {
        host: process.env.DB_HOST || 'localhost',
        port: parseInt(process.env.DB_PORT || '5432', 10),
        name: process.env.DB_NAME || 'myapp_dev',
        user: process.env.DB_USER || 'postgres',
        password: process.env.DB_PASSWORD,
        ssl: process.env.DB_SSL === 'true'
    },
    jwt: {
        secret: process.env.JWT_SECRET,
        expiresIn: process.env.JWT_EXPIRES_IN || '24h'
    },
    email: {
        host: process.env.SMTP_HOST,
        port: parseInt(process.env.SMTP_PORT || '587', 10),
        user: process.env.SMTP_USER,
        pass: process.env.SMTP_PASS
    },
    redis: {
        url: process.env.REDIS_URL || 'redis://localhost:6379'
    }
};

// Zorunlu degiskenleri kontrol et
function zorunluDegiskenleriKontrolEt() {
    const zorunlular = ['DB_PASSWORD', 'JWT_SECRET'];
    const eksikler = zorunlular.filter(v => !process.env[v]);

    if (eksikler.length > 0) {
        console.error('HATA: Zorunlu environment variable eksik:', eksikler.join(', '));
        console.error('Lutfen .env dosyanizi kontrol edin.');
        process.exit(1);
    }
}

zorunluDegiskenleriKontrolEt();

module.exports = config;

Burada config objesini oluşturup export ediyoruz. Projenin her yerinde process.env yazmak yerine bu config modülünü import edip kullanabilirsiniz. Daha temiz ve yönetilebilir bir yapı oluyor. Varsayılan değerler development ortamı için, production'da environment variable'lardan gelecek.

Zorunlu değişken kontrolü de çok önemli. Uygulama başlarken kontrol yaparsanız, eksik bir şifre yüzünden runtime'da hata almak yerine uygulama hemen hata verip durur. Bu çok daha iyi çünkü sorunu anında fark edersiniz.

.env Dosyası ve .gitignore​


JavaScript:
// .env dosyasi (KOK dizinde)
// BU DOSYA ASLA GIT'E COMMIT EDILMEMELI!

/*
NODE_ENV=development
PORT=3000

DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp_dev
DB_USER=postgres
DB_PASSWORD=gizli_sifre_123

JWT_SECRET=cok-uzun-ve-rastgele-bir-string-buraya-32-karakter-min
JWT_EXPIRES_IN=24h

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=uygulama@gmail.com
SMTP_PASS=uygulama-sifresi

REDIS_URL=redis://localhost:6379

API_KEY_STRIPE=sk_test_xxxxx
API_KEY_SENDGRID=SG.xxxxx
*/

// .gitignore dosyasina ekle:
// .env
// .env.local
// .env.production
// .env.*.local

// .env.example dosyasi olustur (bu commit edilir)
/*
NODE_ENV=development
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=myapp_dev
DB_USER=postgres
DB_PASSWORD=BURAYA_SIFRE_YAZIN
JWT_SECRET=BURAYA_UZUN_RASTGELE_STRING_YAZIN
*/

.env dosyasını asla Git'e commit etmeyin, .gitignore'a eklemeyi unutmayın. Bunun yerine .env.example dosyası oluşturun, değerleri boş veya placeholder bırakın ve bunu commit edin. Yeni katılan geliştiriciler bu dosyayı kopyalayıp kendi değerlerini yazar.

Güvenlik Kuralları​


Environment variable yönetiminde birkaç altın kural var. Birincisi, production secret'larını asla development'ta kullanmayın. Her ortamın kendi değişkenleri olsun. İkincisi, secret'ları log'lamayın. console.log(config) yaparsanız şifre log'a düşer. Üçüncüsü, secret rotation yapın, yani belirli aralıklarla şifrelerinizi değiştirin. Son olarak, CI/CD pipeline'ında environment variable'ları güvenli bir şekilde saklayın, GitHub Secrets veya HashiCorp Vault gibi araçlar kullanın.

Bir de production'da .env dosyası kullanmak yerine gerçek environment variable'ları tercih edin. Docker'da ENV, Kubernetes'te ConfigMap/Secret, cloud platformlarında da kendi secret management araçları var. .env dosyası geliştirme ortamı içindir.

Kolay gelsin!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst