Функцыя password_hash

На самой справе функцыя md5 і саленне пароля з яе дапамогай лічыцца састарэлым. Мы вывучалі яе, каб вы зразумелі далейшы матэрыял, а таксама таму, што вы можаце сутыкнуцца з гэтым, працуючы з чужымі праектамі.

Існуе больш дасканалы спосаб атрымаць салёны пароль. Для гэтага выкарыстоўваецца функцыя password_hash. Першым параметрам яна прымае радок, а другім - алгарытм шыфравання (пра яго пазней), і вяртае хэш гэтага радка разам з соляй.

Паспрабуйце некалькі разоў запусціце гэты код:

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

Вы кожны раз будзеце атрымліваць розны вынік і ў гэтым выніку першая частка радка будзе з'яўляцца соляй, а другая частка - салёным паролем.

Хай у нас ёсць хэш, атрыманы з функцыі password_hash і нейкі пароль. Каб праверыць, гэта хэш гэтага пароля ці не, следыць выкарыстоўваць функцыю password_verify - першым параметрам яна прымае пароль, а другім - хэш, і вяртае true ці false.

Давайце паглядзім на прыкладзе:

html<?php
  $password = '12345'; // пароль
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // хэш
  
  if (password_verify($password, $hash)) {
    // хэш ад гэтага пароля
  } else {
    // хэш не ад гэтага пароля
  }
?>

Што гэта дае нам на практыцы: мы можам не ствараць у базе даных асобнае поле для захоўвання солі, не замочвацца з генераваннем гэтай солі - PHP усё зробіць за нас!

Гэта значыць атрымаецца, што ў базе даных у поле password мы будзем захоўваць салёны пароль разам з яго соляй. Пры гэтым хэшаваны пароль будзе мець вялікую даўжыню. Таму ў базе даных нам трэба выправіць памер поля з паролем і ўсталяваць яе ў 60 сімвалаў.

Зараз давайце папраўім код рэгістрацыі. Вось тое, што ёсць зараз:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // даўжыня солі
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // сімвал з ASCII-table
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  соль
  $password = md5($salt . $_POST['password']); // пераўтвараем пароль у салёны хэш
?>

З дапамогай password_hash мы скарацім гэта да:

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

Аналагічным чынам паправіцца код аўтарызацыі:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // атрымліваем карыстальніка па лагіне
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // салёны пароль з БД
    
    // Правяраем адпаведнасць хэша з базы ўведзенаму паролю
    if (password_verify($_POST['password'], $hash)) {
      // усё ок, аўтарызуем...
    } else {
      // пароль не падышоў, вывядзем паведамленне
    }
  } else {
    // карыстальніка з такім лагінам няма, вывядзем паведамленне
  }
?>
Задание 1

Перарабіце вашу аўтарызацыю і рэгістрацыю на новыя вывучаныя функцыі.