【问题标题】:Password Validation in CodeigniterCodeigniter 中的密码验证
【发布时间】:2018-01-08 10:26:55
【问题描述】:

大家好,当我在 codeigniter 中验证登录时,我遇到了这个问题,似乎它没有检查我的数据库中所需的密码。我的数据库中所需的密码是使用此哈希的

$password_hash = password_hash($password, PASSWORD_BCRYPT);

我也在使用这个哈希来测试它的能力和安全性。

我的登录视图中的代码是:

<div class="container">
  <div class="card card-login mx-auto mt-5">
    <div class="card-header">Login</div>
    <div class="card-body">
      <form method = "post" action=<?php echo base_url("Ec_controller/login"); ?> >
        <div class="form-group">
          <label for="Username">Username</label>
          <input class="form-control" id="username" name="username" type="text" aria-describedby="emailHelp" placeholder="Enter Username">
        </div>
        <div class="form-group">
          <label for="Password">Password</label>
          <input class="form-control" id="password" name= "password" type="password" placeholder="Enter Password">
        </div>
        <div class="form-group">
          <div class="form-check">
            <label class="form-check-label">
              <!-- <input class="form-check-input" type="checkbox"> Remember Password</label> -->
          </div>
        </div>        
        <input type="submit" name="submit" id="submit" class="btn btn-primary btn-xm" value="Log In" />
      </form>
      <div class="text-center">
        <!-- <a class="d-block small" href="#">Forgot Password?</a> -->
      </div>
    </div>
  </div>
</div>

在我的控制器上:

public function login(){


    $this->load->library('form_validation');

    $this->form_validation->set_rules('username', 'Username', 'required|trim|callback_validate_credentials');
    $this->form_validation->set_rules('password', 'Password', 'required|trim');

    $username = $this->input->post('username');
    $password = $this->input->post('password');
    $user_id ="";

    if($this->form_validation->run()){

            $data = array(
                'log_username' => $username,
                'is_logged_in' =>1

            );
            $this->session->set_userdata($data);
            $sql2 = $this->db->select("log_username, log_password,log_userlevel ")
                             ->from("ec_login")
                             ->where("log_username", $username)
                             ->get();



            foreach($sql2->result() as $user_level){

                $user_id = $user_level->log_userlevel;

            }
            if($user_id == 1){

                redirect('Ec_controller/view_admin');

            }elseif ($user_id == 2) {

                redirect('Ec_controller/view_it');
            }else{

                redirect("Ec_controller/index");
            }

    }else{

        redirect('Ec_controller/index');
    }


}

public function validate_credentials(){

    $this->load->model('Ec_model');

    if($this->Ec_model->can_log_in()){
        return true;
    }else{
        $this->form_validation->set_message('validate_credentials', '<font color=red>Incorrect username/password</font>');
        return false;
    }
}

在我的模型上:

公共函数 can_log_in(){

$this->db->where('log_username', $this->input->post('username'));
$this->db->where('log_password', password_verify($this->input->post('password'), PASSWORD_BCRYPT));       
$query = $this->db->get('ec_login');

  if($query->num_rows() == 1)
   {        
     return true;
   }else{
      return false;
   }
}

当我输入用户名时,它会验证所需的用户名,唯一的问题是密码,无论我输入什么密码,它都会验证并重定向到特定页面/视图,这听起来很疯狂。帮助和一点解释会很有帮助。

【问题讨论】:

    标签: php codeigniter validation


    【解决方案1】:

    在您的登录功能中,您没有根据数据库中的值检查密码,因此查询只是匹配用户名并忽略密码。您需要将以下内容添加到 db 查询中:

    $password_hash = password_hash($password, PASSWORD_BCRYPT);
    ...
    ->where('log_password', $password_hash)
    

    您还应该将此行:$this-&gt;session-&gt;set_userdata($data); 移动到查询下方,并将其放入 if 语句中:

    if ($sql2->num_rows()) {
        $this->session->set_userdata($data);
    }
    

    所以整个事情看起来像:

    $password_hash = password_hash($password, PASSWORD_BCRYPT);

    $sql2 = $this->db->select("log_username, log_password,log_userlevel ")
                                 ->from("ec_login")
                                 ->where("log_username", $username)
                                 ->where('log_password', $password_hash)
                                 ->get();
    if ($sql2->num_rows()) {
        $this->session->set_userdata($data);
    }
    

    【讨论】:

    • 在我的$this-&gt;form_validation-&gt;set_rules('username', 'Username', 'required|trim|callback_validate_credentials'); 中是回调函数validate_credentials(),用于从我的模型类中检查我在 Ec_model 中的数据库上的密码凭据。
    • 我认为你应该把他的 validate_credentials 函数放在不同的地方,看看stackoverflow.com/questions/12878863/…
    • 我想在这里检查表单上的输入密码是否与数据库密码相同。示例:表单输入密码是 abcd,我的数据库密码是 cdef。但是当我在表单上输入 whatever 密码时。示例:表单输入密码为 ae,ui,ou 这些值传递给控制器​​和模型,它重定向到特定页面/视图
    【解决方案2】:

    解决了。

    因为没有仔细阅读 PHP 手册中 password_verify() 的用法,我完全傻了。好吧,我现在终于明白了。这是我对更新问题的回答。

    public function login(){
    
    
    $this->load->library('form_validation');
    
    $this->form_validation->set_rules('username', 'Username', 'required|trim');
    $this->form_validation->set_rules('password', 'Password', 'required|trim');
    
    $username = $this->input->post('username');
    $password = $this->input->post('password');
    $user_id ="";
    
    if($this->form_validation->run()!= true){
    
    
            redirect('Ec_controller/index');
    
    
    }else{
    
    
    
            $sql2 = $this->db->select("log_username, log_password,log_userlevel ")
                             ->from("ec_login")
                             ->where("log_username", $username)
                             ->get();
    
    
    
            foreach($sql2->result() as $user_level){
    
                $user_id = $user_level->log_userlevel;
                $user_password_db = $user_level->log_password;
    
            }
    
            $data = array(
    
                'log_username'  =>$username,
                'log_userlevel' =>$user_id,
                'log_password'  =>$user_password_db,
                'is_logged_in'  =>1
    
            );
            $this->session->set_userdata($data);
    
    
            if(password_verify($password,$user_password_db) && $user_id == 1){
    
                redirect('Ec_controller/view_admin');
    
    
            }elseif (password_verify($password,$user_password_db) && $user_id == 2) {
    
                redirect('Ec_controller/view_it');
            }else{
    
                redirect("Ec_controller/index");
            }
    
    
    
    
    
    }
    

    }

    这让我头疼,但这是值得的,我为结果感到高兴。

    【讨论】:

    • 很高兴您找到了解决方案! :)
    【解决方案3】:
    callback in your controller:
    
    public function password_check($str)
    {
       if (preg_match('#[0-9]#', $str) && preg_match('#[a-zA-Z]#', $str)) {
         return TRUE;
       }
       return FALSE;
    }
    Then, update your rule to use it:
    
    $this->form_validation->set_rules('password', 'Password', 'required|matches[passconf]|min_length[8]|alpha_numeric|callback_password_check');
    

    【讨论】:

    • 不更新密码,而是检查用户输入的密码是否与数据库用户密码相同。
    • 公共函数登录($data) { $condition = "user_name =" . “'”。 $data['用户名'] 。 “' 和 ” 。 “用户密码=”。 “'”。 md5($data['password']) 。 "'"; $this->db->select('*'); $this->db->from('user_login'); $this->db->where($condition); $this->db->limit(1); $query = $this->db->get(); if ($query->num_rows() == 1) { return true; } 否则 { 返回假; }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-21
    相关资源
    最近更新 更多