表格不从数据库中读取信息

时间:2016-10-11 15:30:10

标签: php forms prepared-statement

我正在从我不时使用的框架配置登录表单。但是,由于某种原因,$tryagain错误仍然存​​在。我知道我的数据库中的信息是正确的,我甚至在数据库中编辑了密码以删除哈希以消除这个问题。

有没有人知道为什么它再次抛出尝试错误说信息有误?我可以注册用户,然后将其重定向到此页面以允许他们登录,因此登录是唯一的问题。

如果您需要框架中的更多代码,请告诉我们。我不想发布大量代码。

ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once 'core/init.php';

if(Input::exists()) {
    if(Token::check(Input::get('token'))) {

        $validate = new Validate();
        $validation = $validate->check($_POST, array(
            'username' => array('required' => true),
            'password' => array('required' => true)
        ));

        if($validation->passed()) {
            $user = new User();

            $remember = (Input::get('remember') === 'on') ? true : false;
            $login = $user->login(Input::get('username'), Input::get('password'), $remember);
            //var_dump($login);

            if($login) {
                Redirect::to('index');
            } else {
                echo $tryagain = '<span class="signinpanel">' . "The information you entered did not match our records." . '</span>';
            }

        } else {
            foreach($validation->errors() as $error) {
                echo $error, '<br>';
            }
        }
    }
}

表格

<?php
    if(Session::exists('home')) {
        echo '<p>' . Session::flash('home') . '</p>';
    }
?>
<form name="Sign In" action="" method="POST" autocomplete="on" accept-charset= "utf-8">
        <div class="field"> 
            <label for="username">Username</label>
            <input type="text" name="username" autocomplete="on" required>
        </div>
        <div class="field">
            <label for="password">Password</label>
            <input type="password" name="password" autocomplete="off" required>
        </div>  
        <div class="field"> 
            <label for="remember">
            <input type="checkbox" name="remember" id="remember"> Remember me
            </label>
        </div><br>
        <input type="hidden" name="token" value="<?php echo Token::generate(); ?>">
        <input type="submit" value="Sign In"> 
    </form> 

登录功能

public function login($username = null, $password = null, $remember = false)    {

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)) {
            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;
        }
    }

}
return false;

}

哈希文件

class Hash {
    public static function make($string, $salt = '') {
        return hash('sha256', $string . $salt);
    }

    public static function salt($length) {
        return mcrypt_create_iv($length);
    }

    public static function unique() {
        return self::make(uniqid());
    }
}

1 个答案:

答案 0 :(得分:1)

我认为您的错误在于您在此处进行的检查:

if($this->data()->password === Hash::make($password, $this->data()->salt)) {
        Session::put($this->_sessionName, $this->data()->id);

如果我正确读取了这个,你正在获取用户输入的值,然后创建一个全新的密码哈希值,并输入一个新的随机盐。每次代码执行时该值都会改变但是(非常)不太可能与输入密码相同。

最初这个答案是基于Laravel库:

而不是使用Hash:make使用Hash::check作为进入该区块的守卫:

if(Hash::check($this->data()->password, $password)){
        Session::put($this->_sessionName, $this->data()->id);

这应该让login()函数返回true

然而,由于@becky表示他们没有使用Laravel,因此需要更一般的答案:

您遇到的根本问题是您要根据加密(哈希)密码检查明文密码。在所有优秀的算法中,这不会是同样的事情,这就是为什么它永远不会从函数中返回真实。

您需要做的是检查用户输入内容的散列版本:Hash::make($password, $this->data()->salt),其中包含您已存储的值(因为您只存储散列版本)。如果您可以更改代码以比较这两个值,则它们应该相同,因此身份运算符===将返回true值。

进一步的讨论和一些调试表明,从数据库返回的内容并不是

在页面上创建的内容。
Hash::make($password, $this->data()->salt)

语句。仔细观察后发现,db上列的长度已从64个字符减少到50.由于Hash::make()函数返回了64个字符的哈希值,因此两者永远不会相等。重新构建该DB列并重新生成密码哈希解决了问题。