我正在尝试创建一个表单来验证MySQL
数据库中存在的用户名和密码(使用UwAmp
)它有一个名为users
的数据库和一个名为{的表{1}}有2列userdetails
和Username
分别包含Password
和user
作为数据。
我知道我目前没有使用最新的最新安全方法(我想知道这样做之后)。
当页面保持在pass
时,无论细节是否正确,在这两种情况下,页面上的所有内容都会消失。
作为旁注,我可能会对此感到困惑但是有一种方法可以将密码存储在login.php
数据库中,而不仅仅是纯文本。我可以加密吗?
我有以下UwAmp
文件
PHP
<?php
include_once '/includes/db-connect.php'; //Connect to the database
if(isset($_POST["Username"], $_POST["Password"]))
{
$name = $_POST["Username"];
$password = $_POST["Password"];
$result1 = mysqli_query($conn, "SELECT Username, Password FROM userdetails WHERE Username = '".$name."' AND Password = '".$password."'");
while($row=mysql_fetch_assoc($result1))
{
$check_username=$row['Username'];
$check_password=$row['Password'];
}
if($username == $check_username && $password == $check_password) {
header("Location: welcomePage.html");
}
else {
echo "No match.";
}
}
档案
HTML
错误。
<div class="form_login">
<form name="credentials" action="php/login.php" onsubmit="return validateForm();" method="post">
Username:<br>
<input type="text" name="Username" value=""><br>
Pasword:<br>
<input type="password" name="Password" value=""><br><br>
<input type="submit" value="Submit">
</form>
</div>
答案 0 :(得分:0)
问题在于你的查询字符串,因为双引号(“)可以解释$ variables而单引号(')不能。所以删除单引号并将所有查询字符串保存在双引号中,如下所示;
$ result1 = mysqli_query($ conn,“SELECT Username,Password FROM userdetails WHERE Username ='”。mysqli_escape_string($ conn,$ name)。“'AND Password ='”。mysqli_escape_string($ conn,$密码) “';”); 强>
更新了php文件:
<?php
include_once '/includes/db-connect.php'; //Connect to the database
if(isset($_POST["Username"], $_POST["Password"]))
{
$name = $_POST["Username"];
$password = $_POST["Password"];
$result1 = mysqli_query($conn, "SELECT Username, Password FROM userdetails WHERE Username = '".mysqli_escape_string($conn,$name)."' AND Password = '".mysqli_escape_string($conn,$password)"';");
while($row=mysql_fetch_assoc($result1))
{
$check_username=$row['Username'];
$check_password=$row['Password'];
}
if($username == $check_username && $password == $check_password) {
header("Location: welcomePage.html");
}
else {
echo "No match.";
}
}
答案 1 :(得分:0)
然后我会将您引用到hash()调用
上的PHP文档http://metadata.ukfederation.org.uk/ukfederation-metadata.xml
您可以尝试任意数量的哈希加密,以查看哪种最适合您。你说md5()被现代行业标准认为不够安全是正确的。
否则gitHub上有一些库可能也可以正常工作。但是......它们可能不起作用。
希望有所帮助。
答案 2 :(得分:0)
作为一个简单的不安全密钥。
$password = $_POST['password'];
$encrypted_password = hash(-hash_algorith-, $password);
然后插入SQL或检查有效性
- 希望帮助
答案 3 :(得分:0)
简短说明:
mysql_fetch_assoc() expects parameter 1 to be resource, boolean given ...
,因为 mysqli_query 返回 FALSE - 用于表示失败的值 - 而不是mysqli_result(请参阅this)。为什么你有这种情况,由你来发现。我没有看到任何可能产生它的疏忽。Undefined variable: check_username ...
。在这种情况下,中的变量定义和值分配不会发生语句。因此,在 while 语句之外,变量$check_username
和$check_password
被&#34;识别&#34;没有定义。现在,您的首要问题是,您不能使用任何prepared statements以避免SQL injection。因此,不应该使用 mysqli_query ,而应该使用准备sql语句所涉及的函数 - 在本例中是你的 - 并为其中的最终参数标记注入值。
第二个大问题是,如果您决定以明文形式或以不安全的形式保存密码(如md5)。密码应该是高度加密的。对于此任务,我建议您使用password_hash函数 - 使用 PASSWORD_BCRYPT 选项(定义 Blowfish 哈希算法的常量),或者使用< em> PASSWORD_ARGON2I 选项(定义 Argon2 散列算法的常量,从PHP 7.2.0开始引入)。您应该仔细阅读 password_hash 和使用的常量的文档。您可能也想阅读this post。
我在下面编写了一个代码版本,实现了上述两点,希望它能带来更多的清晰度。我使用了面向对象的mysqli库(而不是程序库)和我的命名/编码约定(包括db表) - 因此,我会在我的项目中应用它们。它还包含服务器端的凭据验证部分。实际上是必需的步骤。
原则上,在创建 login.php 代码之前,您应该创建一个负责在db表中保存用户凭据的页面。在该页面中(例如 create-user.php ),对于给定的密码,将创建密码哈希(使用 password_hash 功能)并保存。哈希将是一串至少60个随机字符。相关的页面代码如下所示:
//...
$username = $_POST['username'];
$password = $_POST['password'];
// Create a hash from the posted password.
$passwordHash = password_hash($password, PASSWORD_BCRYPT);
$sql = 'INSERT INTO user_credentials (username, password) VALUES (?, ?)';
$statement = $connection->prepare($sql);
$statement->bind_param('ss', $username, $passwordHash);
$statement->execute();
//...
但是,为了暂时缩短任务,您可以在PHP中使用值pass
创建密码哈希,并手动复制并保存,以及user
值:
// Create a hash from the "pass" value.
$passwordHash = password_hash('pass', PASSWORD_BCRYPT);
echo $passwordHash;
建议:对于应用错误/异常处理,您可以查看this和this教程文章。
最后,这是我使用的登录页面,数据库连接代码,表结构和文件系统结构:
<?php
/* Don't use include_once to include the connection page! */
require 'includes/connection.php';
// Operations upon form submission.
if (isset($_POST['submit'])) {
// Validate username.
if (!isset($_POST['username']) || empty($_POST['username'])) {
$errors[] = 'Please provide the username.';
} /* Other validations here using "else if". For example on username length. */
// Validate password.
if (!isset($_POST['password']) || empty($_POST['password'])) {
$errors[] = 'Please provide the password.';
} /* Other validations here using "else if". For example on password length. */
if (!isset($errors)) { // No errors.
// Get posted credentials.
$username = $_POST['username'];
$password = $_POST['password'];
/*
* The SQL statement to be prepared. Notice the so-called markers,
* e.g. the "?" signs. They will be replaced later with the
* corresponding values when using mysqli_stmt::bind_param.
*
* @link http://php.net/manual/en/mysqli.prepare.php
*/
$sql = 'SELECT username, password
FROM user_credentials
WHERE username = ?
LIMIT 1';
/*
* Prepare the SQL statement for execution - ONLY ONCE.
*
* @link http://php.net/manual/en/mysqli.prepare.php
*/
$statement = $connection->prepare($sql);
/*
* Bind variables for the parameter markers (?) in the
* SQL statement that was passed to prepare(). The first
* argument of bind_param() is a string that contains one
* or more characters which specify the types for the
* corresponding bind variables.
*
* @link http://php.net/manual/en/mysqli-stmt.bind-param.php
*/
$statement->bind_param('s', $username);
/*
* Execute the prepared SQL statement.
* When executed any parameter markers which exist will
* automatically be replaced with the appropriate data.
*
* @link http://php.net/manual/en/mysqli-stmt.execute.php
*/
$statement->execute();
/*
* Get the result set from the prepared statement.
*
* NOTA BENE:
* Available only with mysqlnd ("MySQL Native Driver")! If this
* is not installed, then uncomment "extension=php_mysqli_mysqlnd.dll" in
* PHP config file (php.ini) and restart web server (I assume Apache) and
* mysql service. Or use the following functions instead:
* mysqli_stmt::store_result + mysqli_stmt::bind_result + mysqli_stmt::fetch.
*
* @link http://php.net/manual/en/mysqli-stmt.get-result.php
* @link https://stackoverflow.com/questions/8321096/call-to-undefined-method-mysqli-stmtget-result
*/
$result = $statement->get_result();
/*
* Fetch the credentials into an associative array.
* If no record is found, the operation returns NULL.
*/
$credentials = $result->fetch_array(MYSQLI_ASSOC);
/*
* Free the memory associated with the result. You should
* always free your result when it is not needed anymore.
*
* @link http://php.net/manual/en/mysqli-result.free.php
*/
$result->close();
/*
* Close the prepared statement. It also deallocates the statement handle.
* If the statement has pending or unread results, it cancels them
* so that the next query can be executed.
*
* @link http://php.net/manual/en/mysqli-stmt.close.php
*/
$statement->close();
/*
* Close the previously opened database connection. Not really needed,
* because PHP closes the connection after script processing finishes.
*
* @link http://php.net/manual/en/mysqli.close.php
*/
$connection->close();
if (isset($credentials) && $credentials) { // Record found.
$fetchedUsername = $credentials['username'];
$fetchedPasswordHash = $credentials['password'];
/*
* Compare the posted username with the one saved in db and the posted
* password with the password hash saved in db using password_hash.
*
* @link https://secure.php.net/manual/en/function.password-verify.php
* @link https://secure.php.net/manual/en/function.password-hash.php
*/
if (
$username === $fetchedUsername &&
password_verify($password, $fetchedPasswordHash)
) {
header('Location: welcome.html');
exit();
} else {
$errors[] = 'Invalid credentials. Please try again.';
}
} else {
$errors[] = 'No credentials found for the given user.';
}
}
}
echo '<pre>' . print_r(password_hash('pass', PASSWORD_BCRYPT), TRUE) . '</pre>';
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes" />
<meta charset="UTF-8" />
<!-- The above 3 meta tags must come first in the head -->
<title>Demo - Login</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#username').focus();
});
function validateForm() {
return true;
}
</script>
<style type="text/css">
body {
padding: 30px;
}
label {
display: block;
font-weight: 400;
}
input[type="text"],
input[type="password"] {
display: block;
margin-bottom: 20px;
}
button {
display: block;
padding: 7px 10px;
background-color: #8daf15;
color: #fff;
border: none;
}
.messages {
margin-bottom: 20px;
}
.messages .error {
color: #c00;
}
</style>
</head>
<body>
<div class="messages">
<?php
if (isset($errors)) {
foreach ($errors as $error) {
?>
<div class="error">
<?php echo $error; ?>
</div>
<?php
}
}
?>
</div>
<div class="form_login">
<form name="credentials" action="" method="post" onsubmit="return validateForm();">
<label for="username">Username:</label>
<input type="text" id="username" name="username" value="<?php echo isset($username) ? $username : ''; ?>">
<label for="password">Password:</label>
<input type="password" id="password" name="password" value="<?php echo isset($password) ? $password : ''; ?>">
<button type="submit" name="submit" value="submit">
Submit
</button>
</form>
</div>
</body>
</html>
<?php
// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'users');
define('USERNAME', 'youruser');
define('PASSWORD', 'yourpass');
/*
* Enable internal report functions. This enables the exception handling,
* e.g. mysqli will not throw PHP warnings anymore, but mysqli exceptions
* (mysqli_sql_exception).
*
* MYSQLI_REPORT_ERROR: Report errors from mysqli function calls.
* MYSQLI_REPORT_STRICT: Throw a mysqli_sql_exception for errors instead of warnings.
*
* @link http://php.net/manual/en/class.mysqli-driver.php
* @link http://php.net/manual/en/mysqli-driver.report-mode.php
* @link http://php.net/manual/en/mysqli.constants.php
*/
$mysqliDriver = new mysqli_driver();
$mysqliDriver->report_mode = (MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
/*
* Create a new db connection.
*
* @see http://php.net/manual/en/mysqli.construct.php
*/
$connection = new mysqli(HOST, USERNAME, PASSWORD, DATABASE, PORT);
CREATE TABLE `user_credentials` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(100) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
includes
connection.php
login.php
welcome.html
答案 4 :(得分:-2)
您的代码看起来很稳固。我建议这个添加加密。
$password = $_POST[$password];
$password = md5($password);
这应该可以让你到达目的地。
希望有所帮助。