Funksioni password_hash

Në fakt, funksioni md5 dhe kripja e fjalëkalimit me ndihmën e tij konsiderohet i vjetëruar. E kemi studiuar atë në mënyrë që ju të kuptoni materialin e mëtejshëm, dhe gjithashtu sepse mund të hasni në të duke punuar me projekte të huaja.

Ekziston një mënyrë më e përsosur për të marrë një fjalëkalim të kripur. Për këtë përdoret funksioni password_hash. Si parametër të parë ai pranon një varg, dhe si të dytë - algoritmin e enkriptimit (për të më vonë), dhe kthen hash-in e atij vargu së bashku me kripën.

Provoni ta ekzekutoni këtë kod disa herë:

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

Çdo herë do të merrni një rezultat të ndryshëm dhe në këtë rezultat pjesa e parë e vargut do të jetë kripja, kurse pjesa e dytë - fjalëkalimi i kripur.

Le të themi se kemi një hash, të marrë nga funksioni password_hash dhe një fjalëkalim. Për të kontrolluar nëse ky është hash i atij fjalëkalimi apo jo, duhet përdorur funksioni password_verify - si parametër të parë ai merr fjalëkalimin, kurse si të dytë - hash-in, dhe kthen true ose false.

Le të shohim një shembull:

html<?php
  $password = '12345'; // fjalëkalimi
  $hash = '$2y$10$xoYFX1mFPxBSyxaRe3iIRutxkIWhxGShzEhjYUVd3qpCUKfJE1k7a'; // hash-i
  
  if (password_verify($password, $hash)) {
    // hash nga ky fjalëkalim
  } else {
    // hash jo nga ky fjalëkalim
  }
?>

Çfarë na jep kjo në praktikë: ne mund të mos krijojmë në bazën e të dhënave një fushë të veçantë për ruajtjen e kripës, të mos shqetësohemi me gjenerimin e asaj kripe - PHP do të bëjë gjithçka për ne!

Kjo do të thotë se në bazën e të dhënave në fushën password ne do të ruajmë fjalëkalimin e kripur së bashku me kripën e tij. Në këtë rast, fjalëkalimi i hash-uar do të ketë një gjatësi më të madhe. Prandaj në bazën e të dhënave duhet të korrigjojmë madhësinë e fushës së fjalëkalimit dhe ta vendosim atë në 60 karaktere.

Tani le të korrigjojmë kodin e regjistrimit. Ja çfarë kemi tani:

html<?php
  function generateSalt()
  {
    $salt = '';
    $saltLength = 8; // gjatësia e kripës
    
    for($i = 0; $i < $saltLength; $i++) {
      $salt .= chr(mt_rand(33, 126)); // karakter nga ASCII-table
    }
    
    return $salt;
  }
  
  $salt = generateSalt(); //  kripja
  $password = md5($salt . $_POST['password']); // e shndërrojmë fjalëkalimin në hash të kripur
?>

Me ndihmën e password_hash ne do ta zvogëlojmë këtë në:

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

Në mënyrë të ngjashme do të korrigjohet edhe kodi i autorizimit:

html<?php
  $login = $_POST['login'];
  
  $query = "SELECT * FROM users WHERE login='$login'"; // marrim përdoruesin sipas emrit të përdoruesit
  $res = mysqli_query($link, $query);
  $user = mysqli_fetch_assoc($res);
  
  if (!empty($user)) {
    $hash = $user['password']; // fjalëkalimi i kripur nga DB
    
    // Kontrollojmë përputhjen e hash-it nga bazë me fjalëkalimin e futur
    if (password_verify($_POST['password'], $hash)) {
      // gjithçka në rregull, autorizojmë...
    } else {
      // fjalëkalimi nuk përputhet, do të shfaqim një mesazh
    }
  } else {
    // nuk ka përdorues me këtë emër përdoruesi, do të shfaqim një mesazh
  }
?>
Задание 1

Riktheni autorizimin dhe regjistrimin tuaj me funksionet e reja të studiuara.