A password_hash függvény

Valójában a md5 függvény és a jelszó sózással együtt való hashelése elavultnak számít. Azért tanulmányoztuk, hogy megértsétek a további anyagot, és azért is, mert találkozhattok vele más projektekkel dolgozva.

Létezik egy kifinomultabb mód a sózott jelszó előállítására. Ehhez a password_hash függvényt használják. Első paraméterként egy karakterláncot fogad, második paraméterként pedig a titkosítási algoritmust (erről később), és visszaadja a karakterlánc hash-ét a sóval együtt.

Próbáld meg néhányszor futtatni ezt a kódot:

html<?php
  echo password_hash('12345', PASSWORD_DEFAULT);
?>

Minden alkalommal más eredményt kapsz, és ebben az eredményben a karakterlánc első része lesz a só, a második rész pedig a sózott jelszó.

Tegyük fel, hogy van egy hash-ünk, amelyet a password_hash függvényből kaptunk, és valamilyen jelszó. Annak ellenőrzéséhez, hogy ez ennek a jelszónak a hash-e vagy sem, a password_verify függvényt kell használni - első paraméterként a jelszót fogadja, másodikként pedig a hash-t, és true-t vagy false-t ad vissza.

Nézzük egy példán:

html<?php
  $password = '12345'; // jelszó
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash
  
  if (password_verify($password, $hash)) {
    // hash ehhez a jelszóhoz
  } else {
    // a hash nem ehhez a jelszóhoz tartozik
  }
?>

Mit ad ez nekünk a gyakorlatban: nem kell külön mezőt létrehoznunk az adatbázisban a só tárolására, nem kell a só generálásával bajlódnunk - a PHP megcsinálja helyettünk!

Vagyis úgy fog kiderülni, hogy az adatbázisban a password mezőben a sózott jelszót tároljuk a sójával együtt. Eközben a hash-elt jelszó nagyobb hosszúságú lesz. Ezért az adatbázisban ki kell javítanunk a jelszómező méretét, és 60 karakterre kell beállítanunk.

Most javítsuk ki a regisztráció kódját. Itt van, ami most van:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // a só hossza
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // karakter az ASCII-táblából
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  só
  $password = md5($salt . $_POST['password']); // átalakítjuk a jelszót sózott hash-é
?>

A password_hash segítségével ezt le tudjuk rövidíteni erre:

html<?php
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
?>

Hasonló módon módosul a bejelentkezés kódja is:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // lekérjük a felhasználót a felhasználónév alapján
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // sózott jelszó az adatbázisból
    
    // Ellenőrizzük az adatbázisból származó hash és a beírt jelszó egyezését
    if (password_verify($_POST['password'], $hash)) {
      // minden rendben, bejelentkeztetjük...
    } else {
      // a jelszó nem megfelelő, üzenetet jelenítünk meg
    }
  } else {
    // nincs ilyen felhasználónévvel rendelkező felhasználó, üzenetet jelenítünk meg
  }
?>
Задание 1

Alakítsd át a bejelentkezésedet és regisztrációdát az újonnan tanult függvényekre.