Php PDO登录错误,如果($this->;data()->;password===Hash::make($password,$this->;data()->;salt)){始终返回错误
我正在尝试使用PDO创建一个PHP登录/注册系统。注册部分工作正常,但是,当我尝试登录时,总是会收到一个错误,告诉我密码无效,即使它是正确的密码 我将在这里添加一些脚本,并在下面进行更多解释 Register.php:Php PDO登录错误,如果($this->;data()->;password===Hash::make($password,$this->;data()->;salt)){始终返回错误,php,login,pdo,Php,Login,Pdo,我正在尝试使用PDO创建一个PHP登录/注册系统。注册部分工作正常,但是,当我尝试登录时,总是会收到一个错误,告诉我密码无效,即使它是正确的密码 我将在这里添加一些脚本,并在下面进行更多解释 Register.php: <?php require_once 'core/init.php'; $user = new User(); if ($user->isLoggedIn()) { Redirect::to('index.php');
<?php
require_once 'core/init.php';
$user = new User();
if ($user->isLoggedIn()) {
Redirect::to('index.php');
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Register</title>
<link rel="icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="style/global.css">
<script src="js/main.js"></script>
</head>
<body>
<input type="checkbox" id="toggle-left">
<input type="checkbox" id="toggle-right">
<div class="page-wrap">
<?php require_once 'includes/header.php'; ?>
<?php require_once 'includes/navbar.php'; ?>
<?php require_once 'includes/profilebar.php'; ?>
<div class="page-content">
<form action="" method="post">
<h1>Register new account</h1>
<div class="inset">
<?php
if(Input::exists()) {
if (Token::check(Input::get('token'))) {
$validate = new Validate();
$validation = $validate->check($_POST, array(
'username' => array(
'required' => true,
'min' => 3,
'max' => 200,
'first_not_numeric' => true,
'unique' => 'users',
'alias' => 'Username'
),
'password' => array(
'required' => true,
'min' => 6,
'alias' => 'Password'
),
'password_again' => array(
'alias' => 'Password confirmation', // <--- using the alias
'required' => true,
'matches' => 'password'
),
'email' => array(
'required' => true,
'min' => 5,
'max' => 200,
'email' => true,
'unique' => 'users',
'alias' => 'Email'
),
'first_name' => array(
'max' => 100,
'alias' => 'First name'
),
'last_name' => array(
'max' => 100,
'alias' => 'Last name'
),
'gender' => array(
'required' => true,
'alias' => 'Gender'
)
));
if ($validation->passed()) {
$user = new User();
$salt = Hash::salt(100);
$k1 = hash('sha256', Input::get('email'));
$k2 = hash('sha256', mt_rand(10000,99999).time().Input::get('email'));
$k3 = hash('sha256', mt_rand(100000,999999).time().Input::get('username'));
try {
$user->create(array(
'username' => Input::get('username'),
'password' => Hash::make(Input::get('password'), $salt),
'salt' => $salt,
'email' => Input::get('email'),
'email_code' => Input::get('email_code'),
'k1' => $k1,
'k2' => $k2,
'k3' => $k3,
'first_name' => Input::get('first_name'),
'last_name' => Input::get('last_name'),
'gender' => Input::get('gender'),
'avatar' => $user->defaultProfilePic(),
'joined' => date('Y-m-d H:i:s'),
'group' => 1
));
if (!file_exists("users/Input::get('username')")) {
mkdir('users/'.Input::get('username'), 0755);
}
User::sendActivation(Input::get('email'), 'Email verification', 'Hello, '.Input::get('username').',
<br>
Please activate your account!<br>
<a href="http://www.soldiersofwar.esy.es/activate.php?k1='.$k1.'&email_code='.Input::get('email_code').'&k2='.$k2.' &k3='.$k3.'">Click here to activate your account!</a>
<br><br>
Copy and paste this link if the one above doesn\'t work.<br>
http://www.soldiersofwar.esy.es/activate.php?k1='.$k1.'&email_code='.Input::get('email_code').'&k2='.$k2.' &k3='.$k3.'
<br>
Thank you very much,<br>
Soldiers Of War Staff');
Session::flash('home', 'Please activate your account!');
Redirect::to('index.php');
} catch(Exception $e) {
die($e->getMessage());
}
} else {
foreach ($validation->errors() as $error) {
echo '<i class="fa fa-exclamation-triangle"></i> ', $error, '<br />';
echo '<br />';
}
}
}
}
?>
<!-- Username -->
<div>
<label for="username">USERNAME</label>
<input type="text" name="username" id="username" value="<?php echo escape(Input::get('username')); ?>" required>
</div>
<!-- Password -->
<div>
<label for="password">ENTER A PASSWORD</label>
<input type="password" name="password" id="password" required>
</div>
<!-- Confirm Password -->
<div>
<label for="password_again">CONFIRM PASSWORD</label>
<input type="password" name="password_again" id="password_again" required>
</div>
<!-- Email Address -->
<div>
<label for="email">EMAIL ADDRESS</label>
<input type="email" name="email" id="email" value="<?php echo escape(Input::get('email')); ?>" required>
</div>
<!-- First Name -->
<div>
<label for="first_name">FIRST NAME</label>
<input type="text" name="first_name" id="first_name" value="<?php echo escape(Input::get('first_name')); ?>">
</div>
<!-- Last Name -->
<div>
<label for="last_name">LAST NAME</label>
<input type="text" name="last_name" id="last_name" value="<?php echo escape(Input::get('last_name')); ?>">
</div>
<!-- Gender -->
<div>
<label for="gender">GENDER</label>
<select class="gender" id="gender" name="gender" required>
<option value="">Select Gender:</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
</div>
<!-- Token -->
<input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
<!-- Activation -->
<input type="hidden" name="email_code" value="<?php echo md5('username' + microtime()); ?>" />
<!-- Submit button -->
<p class="p-container">
<input type="submit" name="go" id="go" value="Register new account">
</p>
</form>
</div>
<?php require_once 'includes/footer.php'; ?>
</div>
</body>
</html>
哈希类:
// I am assuming you have user input password
// you want to verify in variable $password_input
// and that you have already retrieved password hash
// from DB and have that stored in $password_hash
$password_input = ...;
$password_hash = ...;
$passwords_match = password_verify($password_input, $password_hash);
if (false === $passwords_match) {
// password does not match. abort login
} else {
// password match. log user in
}
根据您所说的,如果相同的代码在另一个项目中工作。我建议您检查数据库。检查散列长度,您应该将其设置为足够大,以适合整个散列(它们通常非常长)
当列长度小于实际值时,DB将存储哈希的截断版本,因此密码检查将始终失败。让我使用password\u hash()
和password\u verify()为您提供另一个示例
正如我在上面的评论中所建议的那样。我想你会发现这可以大大简化你的设计
首先让我们讨论DB模式。对于这个用例,您只需要一个与保存密码哈希相关的DB列。对于这个练习,我们假设它是varchar(255),这是一个很好的建议列大小
要根据输入密码创建哈希,代码如下所示:
要验证密码,代码如下所示:
如您所见,散列生成和散列验证每个都需要一行代码。没有比这更简单的了。您是否能够在函数中输出$this->data()->password
?其失败的条件显然是如果($this->data()->password===hash::make($password,$this->data()->salt))
所以输出这两个函数,看看它们是否匹配为什么不使用PHP内置的密码\u散列
密码\u验证
函数?当我输出时,我在数据库中得到散列值。但是如果我输出新的散列,它就不一样了,但是,当我输出salt或输入的密码时,它们是正确的@zgr024,我不知道这些存在当我开始编码的时候,我不知道如何很好地使用它们,以至于我不知道在我的代码中应该修改什么@MikeBrant@Busarna4您可能需要阅读文档中的功能。如果您没有真正增加任何价值(在安全方面),那么重新发明轮子就没有多大意义这些功能实际上将简化您的设计,消除您单独生成和存储盐的需要(而且可能不太安全)。您还可以自动利用PHP中引入的哈希方法的任何改进,而无需进行任何代码更改。我也考虑过这一点,但并非如此。哈希值约为130个字符,但为了安全起见,在数据库中我将其设置为255。此外,salt值约为100个字符,我将其设置为另一个证明这不是答案的原因是,即使第一个字符也不相同,例如,在数据库中,一个字符以“cf”(不带“”)开头,而新的哈希以“87”(不带“”)开头@meda提前谢谢,布萨纳你试过迈克的建议了吗?你需要密码哈希的例子吗?不,我没有试过。如果你有时间给我举个例子,那就太好了@meda
public function login($username = null, $password = null, $remember = false, $validate = null) {
if (!$username && !$password && $this->exists()) {
Session::put($this->_sessionName, $this->data()->id);
} else {
$user = $this->find($username);
if ($user) {
if ($this->data()->password === Hash::make($password, $this->data()->salt)) {
if (1 === intval($this->data()->activated)) {
Session::put($this->_sessionName, $this->data()->id);
if ($remember) {
$hash = Hash::unique();
$hashCheck = $this->_db->get('users_session', array('user_id', '=', $this->data()->id));
if (!$hashCheck->count()) {
$this->_db->insert('users_session', array(
'user_id' => $this->data()->id,
'hash' => $hash
));
} else {
$hash = $hashCheck->first()->hash;
}
Cookie::put($this->_cookieName, $hash, Config::get('remember/cookie_expiry'));
}
return true;
} else {
$validate->addError('You need to activate your account before you login!');
}
} else {
$validate->addError('Invalid password!');
}
} else {
$validate->addError('That username does not exist!');
}
}
return false;
}
<?php
class Hash {
public static function make($string, $salt = '') {
return hash('sha512', $string . $salt);
}
public static function salt($length) {
return mcrypt_create_iv($length);
}
public static function unique() {
return self::make(uniqid());
}
}
// I assume you have sanitized the password at this point
// and stored in this $password variable.
// You should also enforce password length limit of 72 characters.
$password = ...;
$password_hash = password_hash($password, PASSWORD_DEFAULT);
if(false === $password_hash) {
// something went wrong. log error
} else {
// make your SQL insert to single password_hash field
// note that the hash itself contains information on
// the encryption methodology used and the salt
// that was randomly generated to create the hash
}
// I am assuming you have user input password
// you want to verify in variable $password_input
// and that you have already retrieved password hash
// from DB and have that stored in $password_hash
$password_input = ...;
$password_hash = ...;
$passwords_match = password_verify($password_input, $password_hash);
if (false === $passwords_match) {
// password does not match. abort login
} else {
// password match. log user in
}