Tato odpověď je pro hashování, password_hash() a password_verify() . Pro mysqli i pdo. Odkaz ve spodní části obsahuje další odkazy a pár slov o solích a podobně.
Je důležité nepoužívat data dodaná uživatelem přímo s výběry a vkládáními. Raději svažte parametry a volejte připravené příkazy na Vyhněte se útokům sql injection . Hesla by nikdy neměla být v databázích ukládána jako prostý (čistý text). Spíše by měly být odesílány prostřednictvím jednosměrných hashů.
Také poznamenejte. Toto zobrazuje hashování registrace a ověření přihlášení. Není plně vyfouknutá funkcionalita Snažím se nakopnout codecanyon za deset babek ... tak, aby ukazoval přeregistraci e-mailové adresy (přihlašovací jméno) již existuje, provádí aktualizace, pozor. V takovém případě vložka jednoduše selže kvůli jedinečnému klíči nastavenému v db. Nechám to na vás, čtenáři, abyste provedli vyhledávání a řekli „e-mail je již zaregistrován“.
Schéma
CREATE TABLE `user_accounts2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
unique key(email) -- that better be the case
) ENGINE=InnoDB;
Po spuštění přes register.php a uložení uživatele mohou data vypadat takto:
select * from user_accounts2;
+----+-----------+--------------------------------------------------------------+
| id | email | password |
+----+-----------+--------------------------------------------------------------+
| 1 | [email protected] | $2y$10$U6.WR.tiOIYNGDWddfT7kevJU8uiz8KAkdxXpda9e1xuplhC/eTJS |
+----+-----------+--------------------------------------------------------------+
nejprve sekce mysqli
register.php
<?php
mysqli_report(MYSQLI_REPORT_ALL);
error_reporting(E_ALL); // report all PHP errors
ini_set("display_errors", 1); // display them
session_start();
if(isset($_SESSION['userid'])!="") {
// you are already logged in as session has been set
header("Location: safe.php"); // note that this re-direct will at the top of that page
// ... and there to verify the session state so no tricks can be performed
// no tricks and gimmicks
}
if(isset($_POST['register'])) {
$email = $_POST['email'];
$ctPassword = $_POST['password']; // cleartext password from user
$hp=password_hash($ctPassword,PASSWORD_DEFAULT); // hashed password using cleartext one
// pretend the following is locked in a vault and loaded but hard coded here
$host="yourhostname";
$dbname="dbname";
$user="dbuser";
$pwd="password";
$port=3306; // comes along for the ride so I don't need to look up param order below
// end pretend
try {
$mysqli= new mysqli($host, $user, $pwd, $dbname,$port);
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
//echo "I am connected and feel happy.<br/>";
$query = "INSERT INTO user_accounts2(email,password) VALUES (?,?)";
$stmt = $mysqli->prepare($query);
// note the 2 s's below, s is for string
$stmt->bind_param("ss", $email,$hp); // never ever use non-sanitized user supplied data. Bind it
$stmt->execute();
// password is saved as hashed, will be verified on login page with password_verify()
$iLastInsertId=$mysqli->insert_id; // do something special with this (or not)
// redirect to some login page (for now you just sit here)
$stmt->close();
$mysqli->close();
} catch (mysqli_sql_exception $e) {
throw $e;
}
}
?>
<html>
<head>
<title>Register new user</title>
</head>
<body>
<div id="reg-form">
<form method="post">
<table>
<tr>
<td><input type="email" name="email" placeholder="Email" required /></td>
</tr>
<tr>
<td><input type="password" name="password" placeholder="Password" required /></td>
</tr>
<tr>
<td><button type="submit" name="register">Register</button></td>
</tr>
<tr>
<td><a href="index.php">Normal Login In Here</a></td>
</tr>
</table>
</form>
</div>
</body>
</html>
login.php
<?php
mysqli_report(MYSQLI_REPORT_ALL);
error_reporting(E_ALL); // report all PHP errors
ini_set("display_errors", 1); // display them
session_start();
if(isset($_SESSION['userid'])!="") {
// you are already logged in as session has been set
header("Location: safe.php"); // note that this re-direct will at the top of that page
// ... and there to verify the session state so no tricks can be performed
// no tricks and gimmicks
}
if(isset($_POST['login'])) {
$email = $_POST['email'];
$ctPassword = $_POST['password']; // cleartext password from user
// pretend the following is locked in a vault and loaded but hard coded here
$host="yourhostname";
$dbname="dbname";
$user="dbuser";
$pwd="password";
$port=3306; // comes along for the ride so I don't need to look up param order below
// end pretend
try {
$mysqli= new mysqli($host, $user, $pwd, $dbname,$port);
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
//echo "I am connected and feel happy.<br/>";
$query = "select id,email,password from user_accounts2 where email=?";
$stmt = $mysqli->prepare($query);
// note the "s" below, s is for string
$stmt->bind_param("s", $email); // never ever use non-sanitized user supplied data. Bind it
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$dbHashedPassword=$row['password'];
if (password_verify($ctPassword,$dbHashedPassword)) {
echo "right, userid=";
$_SESSION['userid']=$row['id'];
echo $_SESSION['userid'];
// redirect to safe.php (note safeguards verbiage at top of this file about it)
}
else {
echo "wrong";
// could be overkill here, but in logout.php
// clear the $_SESSION['userid']
}
}
else {
echo 'no such record';
}
// remember, there is no iterating through rows, since there is 1 or 0 (email has a unique key)
// also, hashes are one-way functions in the db. Once you hash and do the insert
// there is pretty much no coming back to cleartext from the db with it. you just VERIFY it
$stmt->close();
$mysqli->close();
} catch (mysqli_sql_exception $e) {
throw $e;
}
}
?>
<html>
<head>
<title>Login</title>
</head>
<body>
<div id="reg-form">
<form method="post">
<table>
<tr>
<td><input type="email" name="email" placeholder="Email" required /></td>
</tr>
<tr>
<td><input type="password" name="password" placeholder="Password" required /></td>
</tr>
<tr>
<td><button type="submit" name="login">Login</button></td>
</tr>
</table>
</form>
</div>
</body>
</html>
sekce pdo níže
Až budu mít čas, pravděpodobně zítra, ale prozatím vás odkážu na tuto moji odpověď .