我一直在努力编写最(希望)最先进的登录状态,并记住我的脚本功能,并考虑到安全性。 经过几个小时的测试并使一切工作正常,我遇到了一个简单但尴尬的解决方案的问题。用户登录,如果记得我,则会创建cookie,当用户返回网站时,启动功能会检查cookie,如果存在cookie并且匹配数据库中的auth_key值,该功能将提取用户登录信息(电子邮件,密码) )并使用登录功能重新登录用户。问题是我使用的代码/教程是针对未加密的数据库密码而设计的(例如我想的目的),并且系统正在尝试" bcrypt hash"已经哈希的密码。
我可以想到两个脏修复,最脏的是创建一个辅助登录功能,避免散列密码,仍然很脏的是向login()添加一个参数,指定密码是否经过哈希处理和脚本可以"如果"因此。
有更好的方法吗?
public function login($email, $password, $remember = false) {
global $bcrypt; // Again make get the bcrypt variable, which is defined in init.php, which is included in login.php where this function is called
$query = $this->db->prepare("SELECT password, id, email, username, accountlevel FROM users WHERE email = ?");
$query->bindValue(1, $email);
try{
$query->execute();
$data = $query->fetch();
$stored_password = $data['password']; // stored hashed password
$id = $data['id']; // id of the user to be returned if the password is verified, below.
$email = $data['email']; //Stored User email.
$username = $data{'username'}; //Username.
$accountlevel = $data['accountlevel'];
if($bcrypt->verify($password, $stored_password) === true){ // using the verify method to compare the password with the stored hashed password.
// Check if user wants account to be saved in cookie
if($remember)
{
// Generate new auth key for each log in (so old auth key can not be used multiple times in case of cookie hijacking).
$cookie_auth = $bcrypt->randString(10) . $email;
$auth_key = $bcrypt->genHash($cookie_auth);;
$auth_query = $this->db->prepare("UPDATE users SET auth_key = ? WHERE id = ?");
$auth_query->bindValue(1, $auth_key);
$auth_query->bindValue(2, $id);
try{
$auth_query->execute();
setcookie("auth_key", $auth_key, time() + 60 * 60 * 24 * 7, "/", "touringlegends.com", false, true);
}catch(PDOException $e){
die($e->getMessage());
}
}
session_regenerate_id(true);
$session_id = $id;
$session_username = $username;
$session_level = $accountlevel;
$_SESSION['user_id'] = $session_id;
$_SESSION['user_level'] = $session_level;
$_SESSION['user_name'] = $session_username;
$_SESSION['user_lastactive'] = time();
return true; // returning true.
}else{
return false;
}
}catch(PDOException $e){
die($e->getMessage());
}
}
public function initiate()
{
global $general;
$logged_in = false;
if(isset($_SESSION['user_name']))
{
$logged_in = true;
}
// Check that cookie is set
if(isset($_COOKIE['auth_key']))
{
$auth_key = $general->safe_var($_COOKIE['auth_key']);
if($logged_in === false)
{
// Select user from database where auth key matches (auth keys are unique)
$auth_key_query = $this->db->prepare("SELECT username, password FROM users WHERE auth_key = ? LIMIT 1");
$auth_key_query->bindValue(1, $auth_key);
try{
$auth_key_query->execute();
$data = $auth_key_query->fetch();
if($auth_key_query === false)
{
// If auth key does not belong to a user delete the cookie
setcookie("auth_key", "", time() - 3600);
}
else
{
// Go ahead and log in
$this->login($data['username'], $data['password'], true);
}
}catch(PDOException $e){
die($e->getMessage());
}
}
else
{
setcookie("auth_key", "", time() - 3600);
}
}
}