🔐 Geçici Servis - İleride Kaldırılacak

MD5 Muzibu Eski Şifreler

Laravel Password Migration Rehberi

5 Ocak 2026 - Tenant 1001 (Muzibu)

md5 bcrypt tenant-1001 muzibu

📝 Basit Anlatım (Herkes İçin)

Problem: Muzibu'nun eski sisteminde kullanıcı şifreleri MD5 ile saklanıyordu. MD5 artık güvenli değil ve Laravel bcrypt kullanıyor.

Çözüm: Kullanıcı giriş yaptığında, eski şifresi otomatik olarak yeni güvenli formata çevriliyor. Kullanıcı hiçbir şey fark etmiyor, şifre değiştirmek zorunda kalmıyor.

Sonuç: Zamanla tüm kullanıcılar en az bir kez giriş yapacak ve şifreleri otomatik güncellenecek. Herkes geçiş yapınca bu sistemi kaldıracağız.

🔧 Teknik Detaylar (Geliştiriciler İçin)

📁 Dosyalar

  • • app/Services/Auth/LegacyPasswordMigrationService.php
  • • app/Auth/LegacyUserProvider.php
  • • app/Providers/AuthServiceProvider.php
  • • config/auth.php

⚙️ Teknoloji

  • • MD5 → 32 karakter hex string
  • • bcrypt → 60 karakter ($2y$ prefix)
  • • Tenant-aware kontrol
  • • Laravel Log entegrasyonu
🛠️

OLUŞTURMA (4 Adım)

1

Service Dosyasını Oluştur

Ana migration servisi - tüm mantık burada

📁 app/Services/Auth/LegacyPasswordMigrationService.php
Kodu Göster
<?php

namespace App\Services\Auth;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;

/**
 * Legacy MD5 Password Migration Service
 *
 * ⚠️ GEÇİCİ SERVİS - Tüm kullanıcılar migrate olunca kaldırılacak!
 *
 * Arama: md5 muzibu eski şifreler migration
 */
class LegacyPasswordMigrationService
{
    /**
     * Migration aktif olan tenant'lar
     */
    protected array $enabledTenants = [1001]; // Sadece Muzibu

    /**
     * Bu tenant için legacy migration aktif mi?
     */
    public function isEnabled(): bool
    {
        return tenant() && in_array(tenant()->id, $this->enabledTenants);
    }

    /**
     * MD5 hash mi kontrol et (32 karakter hex)
     */
    public function isLegacyHash(string $hash): bool
    {
        return strlen($hash) === 32 && ctype_xdigit($hash);
    }

    /**
     * Legacy şifre doğrula ve migrate et
     *
     * @return bool|null  true=başarılı, false=yanlış şifre, null=legacy değil
     */
    public function validateAndMigrate(Authenticatable $user, string $plainPassword): ?bool
    {
        // Tenant kontrolü
        if (!$this->isEnabled()) {
            return null;
        }

        $storedHash = $user->getAuthPassword();

        // Legacy hash değilse normal auth'a bırak
        if (!$this->isLegacyHash($storedHash)) {
            return null;
        }

        // MD5 kontrolü
        if (md5($plainPassword) !== $storedHash) {
            return false;
        }

        // ✅ Şifreyi bcrypt'e migrate et
        $user->password = Hash::make($plainPassword);
        $user->save();

        // Log tut (takip için)
        Log::channel('single')->info('Legacy MD5 password migrated to bcrypt', [
            'tenant_id' => tenant()->id,
            'user_id' => $user->getAuthIdentifier(),
            'user_email' => $user->email ?? 'N/A',
        ]);

        return true;
    }

    /**
     * Kaç kullanıcı hala MD5 kullanıyor? (İstatistik)
     */
    public function getRemainingLegacyCount(): int
    {
        if (!$this->isEnabled()) {
            return 0;
        }

        return \App\Models\User::whereRaw('LENGTH(password) = 32')->count();
    }
}
2

Custom User Provider Oluştur

Laravel auth sistemine bağlanır

📁 app/Auth/LegacyUserProvider.php
Kodu Göster
<?php

namespace App\Auth;

use App\Services\Auth\LegacyPasswordMigrationService;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Hash;

/**
 * Legacy User Provider
 *
 * ⚠️ GEÇİCİ - MD5 migration tamamlanınca kaldırılacak!
 */
class LegacyUserProvider extends EloquentUserProvider
{
    public function validateCredentials(Authenticatable $user, array $credentials): bool
    {
        $plainPassword = $credentials['password'];

        // Legacy migration servisini çağır
        $migrationService = app(LegacyPasswordMigrationService::class);
        $result = $migrationService->validateAndMigrate($user, $plainPassword);

        // null değilse sonucu döndür (true veya false)
        if ($result !== null) {
            return $result;
        }

        // Legacy değil → Normal Laravel auth
        return Hash::check($plainPassword, $user->getAuthPassword());
    }
}
3

AuthServiceProvider'a Kaydet

Provider'ı Laravel'e tanıt

📁 app/Providers/AuthServiceProvider.php → boot() metoduna ekle
Eklenecek Kodu Göster
use App\Auth\LegacyUserProvider;
use Illuminate\Support\Facades\Auth;

public function boot(): void
{
    // ... mevcut kodlar ...

    // ⚠️ GEÇİCİ: MD5 Legacy Password Migration (Tenant 1001)
    // Tüm kullanıcılar migrate olunca kaldırılacak!
    Auth::provider('legacy', function ($app, array $config) {
        return new LegacyUserProvider(
            $app['hash'],
            $config['model']
        );
    });
}
4

Config'de Driver'ı Değiştir

Auth driver'ı legacy olarak ayarla

📁 config/auth.php → providers.users.driver
Değişikliği Göster
'providers' => [
    'users' => [
        'driver' => 'legacy',  // ⚠️ 'eloquent' → 'legacy' (GEÇİCİ)
        'model' => App\Models\User::class,
    ],
],

✅ Test Etme

1. Muzibu'da MD5 şifreli bir kullanıcı ile giriş yap

2. Giriş başarılı olmalı

3. Log kontrolü:

grep "Legacy MD5 password migrated" storage/logs/laravel.log

4. Database kontrolü (şifre 60 karakter olmalı):

SELECT id, email, LENGTH(password) FROM users WHERE id = X;
🗑️

KALDIRMA (3 Adım)

⚠️ Ne Zaman Kaldırılır?
Tüm kullanıcılar en az bir kez giriş yaptığında. Kontrol komutu:

SELECT COUNT(*) FROM users WHERE LENGTH(password) = 32;
-- Sonuç 0 olmalı
1

Config'i Geri Al

📁 config/auth.php
'driver' => 'legacy', 'driver' => 'eloquent',
2

AuthServiceProvider'dan Kaldır

📁 app/Providers/AuthServiceProvider.php

boot() metodundan şu bloğu sil:

Auth::provider('legacy', function ($app, array $config) { ... });
3

Dosyaları Sil

rm app/Services/Auth/LegacyPasswordMigrationService.php
rm app/Auth/LegacyUserProvider.php

Cache Temizle

php artisan config:clear
php artisan cache:clear

📊 Migration İstatistik Takibi

Kaç kullanıcı migrate oldu?

grep "Legacy MD5 password migrated" storage/logs/laravel.log | wc -l

Kaç kullanıcı hala MD5 kullanıyor?

SELECT COUNT(*) as remaining FROM users WHERE LENGTH(password) = 32;

Migration yüzdesi?

SELECT
  COUNT(CASE WHEN LENGTH(password) > 32 THEN 1 END) as migrated,
  COUNT(CASE WHEN LENGTH(password) = 32 THEN 1 END) as pending,
  ROUND(COUNT(CASE WHEN LENGTH(password) > 32 THEN 1 END) * 100.0 / COUNT(*), 2) as percentage
FROM users;

📋 Özet

Özellik Değer
Etkilenen Tenant Sadece 1001 (Muzibu)
Eski Hash MD5 (32 karakter)
Yeni Hash bcrypt (60 karakter)
Kullanıcı Fark Eder mi? Hayır ✅
Diğer Tenant'lar Etkilenir mi? Hayır ✅
Geçici mi? Evet - İleride kaldırılacak