Selamlar sevgili TurkHackTeam üyeleri, bu konumda sizlere PHP ile nasıl İki Faktörlü Kimlik Doğrulama (2FA) sistemi yapabileceğinizi anlatmaya çalışacağım.
İnternette kimlik doğrulama, sadece kullanıcı adı ve şifre ile yapıldığında bazı güvenlik açıklarına sebebiyet verebilir. Şifrelerin çalınması, hesap bilgilerinin ele geçirilmesi veya kritik bilgilerin ele geçirilmesi gibi senaryolar doğurabilir. Bu konuda devreye İki Faktörlü Kimlik Doğrulama (2FA) girer. 2FA, kullanıcıdan zaman bazlı değişen bir kod ister ve bu kodu kullanıcının Telefon veya bir uygulama aracılığıyla entegre ederek her giriş işleminde doğrulamasını talep eder.
Biz bu konumuzda Google Authenticator kullanarak bu sistemi geliştireceğiz. Öncelikle yapmamız gereken işlem kullanıcılarımız tutulduğu bir veritabanı sağlamak.
XAMPP yardımıyla localhost'umu çalıştırdım ve phpmyadmine giriş yaptım.
2fa adında bir veritabanı oluşturdum ve şu SQL kodunu çalıştırdım;
SQL:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
google_authenticator_secret VARCHAR(32) NULL
);
Bu SQL kodu sayesinde artık users adından bir tablomuz var, tablomuzun kolonlarında kullanıcı id'si, kullanıcı adı, kullanıcı şifresi ve kullanıcıya ait oluşturulacak 2FA QR kodu için bir secret key alanı var.
2FA QR kodunu oluşturmak için bir modül kullanıyoruz
Github Linki
Şimdi tablomuz ve modülümüz hazır ama içeride verimiz yok, kullanıcılardan ilk verileri almak için hemen bir kayıt sayfası yapalım;
2FA QR kodunu oluşturmak için bir modül kullanıyoruz
Github Linki
Şimdi tablomuz ve modülümüz hazır ama içeride verimiz yok, kullanıcılardan ilk verileri almak için hemen bir kayıt sayfası yapalım;
PHP:
<form method="post">
<label for="username">Kullanıcı Adı:</label>
<input type="text" name="username" required>
<label for="password">Şifre:</label>
<input type="password" name="password" required>
<button type="submit">Kayıt Ol</button>
</form>
<?php
require_once 'lib/GoogleAuthenticator.php';
$authenticator = new PHPGangsta_GoogleAuthenticator();
$pdo = new PDO("mysql:host=localhost;dbname=2fa", "root", "");
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = password_hash($_POST['password'], PASSWORD_BCRYPT);
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE username = ?");
$stmt->execute([$username]);
$userExists = $stmt->fetchColumn();
if ($userExists > 0) {
echo "Sistemde aynı kullanıcı adına sahip biri var, başka kullanıcı adı dene!";
} else {
$secret = $authenticator->createSecret();
$stmt = $pdo->prepare("INSERT INTO users (username, password, google_authenticator_secret) VALUES (?, ?, ?)");
$stmt->execute([$username, $password, $secret]);
$qrCodeUrl = $authenticator->getQRCodeGoogleUrl($username, $secret, 'PHP2FA');
echo "Kayıt başarılı! Google Authenticator'da bu QR kodunu tarayın:<br>";
echo '<img src="' . $qrCodeUrl . '" /><br><br>';
echo "QR kodu tarattıktan sonra <a href='login.php'>Giriş Yap</a> sayfasına giderek sisteme giriş yapabilirisiniz!";
}
}
?>
Ne yaptığımıza yukarıdan aşağıya doğru bir bakalım;
Öncelikle bir form oluşturduk kullanıcının girdiği verileri alıp işleyebilmek adına,
sonrasında PHP kodlarımıza başladık, öncelikli olarak GitHub'dan aldığımız modülü sayfaya bir ekledik ve çağırdık, sonrasında da veritabanı bağlantımızı yaptık,
formdan veriler POST edildiğinde koşulunu yazıp kullanıcıdan gelen username değerini aynen alıp password değerini hashledik,
bir sorgu ekledik, eğer ki sisteme daha önceden ako kullanıcı adıyla kayıt olan bir kullanıcı varsa yeni kaydolan kullanıcı bu kullanıcı adını alamamalı, bunun için ufak bir sorgu yazdık,
eğer ki kullanıcı yoksa ve kayıt başarılıysa modül sayesinde yeni bir secret key oluşturduk, kullanıcı bilgilerini ve secret keyi veritabanına kaydettik, yine modül sayesinde kullanıcıya ait bir QR kod ekrana bastırdık ve kullanıcının yapması gerekenleri ekrana yazdırdık.
QR Kod'u Google Authenticator yardımıyla okutup 6 haneli 2FA Kodunuzu uygulamaya kaydettik.
Şimdi giriş sayfamızın kodlarına bakalım;
Öncelikle bir form oluşturduk kullanıcının girdiği verileri alıp işleyebilmek adına,
sonrasında PHP kodlarımıza başladık, öncelikli olarak GitHub'dan aldığımız modülü sayfaya bir ekledik ve çağırdık, sonrasında da veritabanı bağlantımızı yaptık,
formdan veriler POST edildiğinde koşulunu yazıp kullanıcıdan gelen username değerini aynen alıp password değerini hashledik,
bir sorgu ekledik, eğer ki sisteme daha önceden ako kullanıcı adıyla kayıt olan bir kullanıcı varsa yeni kaydolan kullanıcı bu kullanıcı adını alamamalı, bunun için ufak bir sorgu yazdık,
eğer ki kullanıcı yoksa ve kayıt başarılıysa modül sayesinde yeni bir secret key oluşturduk, kullanıcı bilgilerini ve secret keyi veritabanına kaydettik, yine modül sayesinde kullanıcıya ait bir QR kod ekrana bastırdık ve kullanıcının yapması gerekenleri ekrana yazdırdık.
QR Kod'u Google Authenticator yardımıyla okutup 6 haneli 2FA Kodunuzu uygulamaya kaydettik.
Şimdi giriş sayfamızın kodlarına bakalım;
PHP:
<form method="post">
<label for="username">Kullanıcı Adı:</label>
<input type="text" name="username" required>
<label for="password">Şifre:</label>
<input type="password" name="password" required>
<button type="submit">Giriş Yap</button>
</form>
<?php
session_start();
require_once 'lib/GoogleAuthenticator.php';
$authenticator = new PHPGangsta_GoogleAuthenticator();
$pdo = new PDO("mysql:host=localhost;dbname=2fa", "root", "");
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$password = $_POST['password'];
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch();
if ($user && password_verify($password, $user['password'])) {
$_SESSION['username'] = $username;
$_SESSION['secret'] = $user['google_authenticator_secret'];
header('Location: 2fa.php');
} else {
echo "Kullanıcı adı veya şifre hatalı!";
}
}
?>
Form kısmını artık geçiyorum üst tarafta da bahsetmiştim,
PHP kodlarımıza başlayım, bir oturum başlattık ve modülümüzü çekip veritabanı bağlantısını yaptık,
POST edilen kullanıcı adı ve şifreyi birer değişkene kaydettik ve bu bilgileri veritabanına göndererek verilerin doğruluğunu sorguladık,
eğer ki veritabanındaki ile formdaki veriler eşleşiyorsa oturuma kullanıcı adını ve kullanıcının veritabanındaki secret keyini ekledik ve kullanıcıyı 2FA sayfasına yönlendirdik.
Şimdi 2FA kodunu kontrol ettiğimi 2fa.php sayfasının kodlarına bakalım;
PHP kodlarımıza başlayım, bir oturum başlattık ve modülümüzü çekip veritabanı bağlantısını yaptık,
POST edilen kullanıcı adı ve şifreyi birer değişkene kaydettik ve bu bilgileri veritabanına göndererek verilerin doğruluğunu sorguladık,
eğer ki veritabanındaki ile formdaki veriler eşleşiyorsa oturuma kullanıcı adını ve kullanıcının veritabanındaki secret keyini ekledik ve kullanıcıyı 2FA sayfasına yönlendirdik.
Şimdi 2FA kodunu kontrol ettiğimi 2fa.php sayfasının kodlarına bakalım;
PHP:
<form method="post">
<label for="qrcode">Google Authenticator Kodu:</label>
<input type="text" name="qrcode" required>
<button type="submit">Doğrula</button>
</form>
<?php
session_start();
require_once 'lib/GoogleAuthenticator.php';
$authenticator = new PHPGangsta_GoogleAuthenticator();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$qrcode = $_POST['qrcode'];
$secret = $_SESSION['secret'];
$checkResult = $authenticator->verifyCode($secret, $qrcode, 1);
if ($checkResult) {
echo "Giriş başarılı!";
unset($_SESSION['username'], $_SESSION['secret']);
} else {
echo "Kod hatalı!";
}
}
?>
Bir oturum başlattık ve modülümüzü çektik, bu sefer veritabanı bağlantısı yapmadık çünkü zaten veritabanındaki secret keyi oturuma kaydetmiştik veritabanı ile bir işimiz yok,
Bu sayfada aslında işin büyük kısmını yine modül yapıyor, girilen 6 haneli kodu verify ediyor sonuç doğruysa giriş yapıp oturumda doldurduğumuz verileri boşaltıyor.
Konu ve kodlar bu kadar, kodları tek tek koplayayıp yapıştırmamanız adına bir indirme linki bırakıyorum.
Son düzenleme: