我最近在开发 Ubuntu 服务器上安装了 Guacamole,我正在寻找构建一个 PHP 前端“仪表板”类型系统唯一给我带来麻烦的是通过 PHP 对同一个 MySQL DB 进行身份验证,因为它使用密码哈希(sha256)和密码盐。
每次我尝试登录时,我都会得到用户名或密码无效,但是,我知道它是正确的,因为我在 Guacamole 中设置了它。
下面是 MySQL 表结构:
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| user_id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(128) | NO | UNI | NULL | |
| password_hash | binary(32) | NO | | NULL | |
| password_salt | binary(32) | YES | | NULL | |
| disabled | tinyint(1) | NO | | 0 | |
| expired | tinyint(1) | NO | | 0 | |
| access_window_start | time | YES | | NULL | |
| access_window_end | time | YES | | NULL | |
| valid_from | date | YES | | NULL | |
| valid_until | date | YES | | NULL | |
| timezone | varchar(64) | YES | | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
这是我的 login.php
<?php
require("config.php");
$submitted_username = '';
if(!empty($_POST)){
$query = "
SELECT
user_id,
username,
password_hash,
password_salt
FROM guacamole_user
WHERE
username = :username
";
$query_params = array(
':username' => $_POST['username']
);
try{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex){ die("Failed to run query: " . $ex->getMessage()); }
$login_ok = false;
$row = $stmt->fetch();
if($row){
$check_password = hash('sha256', $_POST['password'] . $row['password_salt']);
for($round = 0; $round < 65536; $round++){
$check_password = hash('sha256', $check_password . $row['password_salt']);
}
if($check_password === $row['password_hash']){
$login_ok = true;
}
}
if($login_ok){
unset($row['password_salt']);
unset($row['password_hash']);
$_SESSION['user'] = $row;
header("Location: secret.php");
die("Redirecting to: secret.php");
}
else{
print("Login Failed.");
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="assets/bootstrap.min.js"></script>
<link href="assets/bootstrap.min.css" rel="stylesheet" media="screen">
<style type="text/css">
body { background: url(assets/bglight.png); }
.hero-unit { background-color: #fff; }
.center { display: block; margin: 0 auto; }
</style>
</head>
<body>
<div class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand">PHP Signup + Bootstrap Example</a>
<div class="nav-collapse collapse">
<ul class="nav pull-right">
<li><a href="register.php">Register</a></li>
<li class="divider-vertical"></li>
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown">Log In <strong class="caret"></strong></a>
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px;">
<form action="index.php" method="post">
Username:<br />
<input type="text" name="username" value="<?php echo $submitted_username; ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" />
<br /><br />
<input type="submit" class="btn btn-info" value="Login" />
</form>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="container hero-unit">
<h1>There's secret content to be had within!</h1>
<p>But you can't access it just yet! You'll need to log in first. Use Bootstrap's nifty navbar dropdown to access the form.</p>
<h2>There are 2 ways you can log in:</h2>
<ul>
<li>Try out your own user + password with the <strong>Register</strong> button in the navbar.</li>
<li>Use the default credentials to save time:<br />
<strong>user:</strong> admin<br />
<strong>pass:</strong> password<br /></li>
</ul>
</div>
</body>
</html>