PHP
Meydan okuma - Güvenlik uygulaması
password_hash, CSRF ve güvenlik başlıklarıyla tam bir kimlik doğrulama akışı yazarsın.
Kimlik doğrulama akışı
Bu derste AuthService sınıfını yazarsın. password_hash($pass, PASSWORD_DEFAULT) parolayı bcrypt ile hash'ler; tuz (salt) otomatik üretilir. password_verify($pass, $hash) hash'i doğrular ve zamanlama saldırılarına karşı güvenlidir.
Sınıf üç yöntem daha içerir. csrfToken() ilk çağrıda bin2hex(random_bytes(8)) ile 16 karakterlik bir dize üretir ve saklar. applyHeaders() header() ile X-Frame-Options: DENY ve X-Content-Type-Options: nosniff başlıklarını gönderir. Böylece API yanıtının yanına bir güvenlik katmanı eklersin.
Güvenlik başlıkları
HTTP yanıt başlıkları tarayıcının yanıtı nasıl işleyeceğini belirler. X-Frame-Options: DENY sayfanın başka bir sitede çerçevelenmesini engeller (tıklama kaçırma saldırılarına karşı). X-Content-Type-Options: nosniff tarayıcının MIME türünü tahmin etmesini önler.
PHP'de header("Ad: Değer") çağrısı bu başlıkları gönderir. CLI modunda çıktı üretmeseler de web sunucusunda yanıt başlıklarına eklenirler. applyHeaders() yöntemi tüm başlıkları tek yerden gönderir; böylece korumayı açma/kapama unutmazsın. Üstelik her istekte aynı başlıkları tekrar tekrar yazmazsın.
Uygulama AuthService sınıfını yaz
Başlangıç kodunda Ürün API'si hazır. Şimdi AuthService sınıfını ekle. Özel array $users = [] ve string $csrf = "" özellikleri olsun.
register(string $user, string $pass): void yöntemi password_hash($pass, PASSWORD_DEFAULT) ile hash üretip $users dizisine ekler. login(string $user, string $pass): bool yöntemi kullanıcı yoksa false, varsa password_verify sonucunu döndürür. csrfToken(): string ilk çağrıda bin2hex(random_bytes(8)) ile token üretir. applyHeaders(): void header() ile X-Frame-Options: DENY ve X-Content-Type-Options: nosniff gönderir. Demoyu çalıştır.
Örnek çözümü göster
class AuthService { private array $users = []; private string $csrf = ""; ... } tanımla. register içinde password_hash, login içinde password_verify, csrfToken içinde bin2hex(random_bytes(8)), applyHeaders içinde iki header() çağrısı yaz. Sonra demoyu çalıştır.
Örnek çözüm:
<?php
// Ürün API'si + güvenlik: AuthService yaz
class ProductRepository {
private PDO $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
$this->pdo->exec("CREATE TABLE products (id INTEGER PRIMARY KEY, name TEXT, price INTEGER)");
$stmt = $this->pdo->prepare("INSERT INTO products (name, price) VALUES (?, ?)");
$stmt->execute(["Kale", 5]);
$stmt->execute(["Defter", 15]);
}
public function all(): array {
$rows = $this->pdo->query("SELECT id, name, price FROM products ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
return array_map(fn($r) => [
"id" => (int)$r["id"],
"name" => $r["name"],
"price" => (int)$r["price"]
], $rows);
}
}
function handleGet(PDO $pdo): string {
$repo = new ProductRepository($pdo);
return json_encode(["products" => $repo->all()], JSON_UNESCAPED_UNICODE);
}
class AuthService {
private array $users = [];
private string $csrf = "";
public function register(string $user, string $pass): void {
$this->users[$user] = password_hash($pass, PASSWORD_DEFAULT);
}
public function login(string $user, string $pass): bool {
if (!isset($this->users[$user])) return false;
return password_verify($pass, $this->users[$user]);
}
public function csrfToken(): string {
if ($this->csrf === "") {
$this->csrf = bin2hex(random_bytes(8));
}
return $this->csrf;
}
public function applyHeaders(): void {
header("X-Frame-Options: DENY");
header("X-Content-Type-Options: nosniff");
}
}
// Demo:
$auth = new AuthService();
$auth->register("ayse", "gizli parola");
echo $auth->login("ayse", "gizli parola") ? "giriş: tamam" : "giriş: red";
echo "\n";
echo $auth->login("ayse", "yanlış") ? "giriş: tamam" : "giriş: red";
echo "\n";
echo strlen($auth->csrfToken()) . "\n";
$auth->applyHeaders();
echo "başlıklar: tamam\n";
Kendini test et
-
password_verify çağrısını tamamla
return ____($pass, $this->users[$user]);
Cevabı göster
return password_verify($pass, $this->users[$user]);
-
CSRF token üretmek için hangi fonksiyon kullanılır?
- random_bytes ile bin2hex
- md5 ile zaman damgası
- password_hash ile bcrypt
- sha1 ile kullanıcı adı
Cevabı göster
random_bytes ile bin2hex — Doğru. random_bytes kriptografik olarak güvenli rastgele bayt üretir; bin2hex onu dizeye çevirir.
-
Güvenlik kavramlarını eşleştir
- password_hash
- Parolayı bcrypt ile saklar
- password_verify
- Parolayı hash'e karşı denetler
- bin2hex
- Baytları onaltılık dizeye çevirir
- header
- HTTP yanıt başlığı gönderir
Sıradaki ders: Meydan okuma - Tasarım desenleri