You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CodeIgniter 3中实现BCRYPT密码哈希算法?

在CodeIgniter 3中实现BCRYPT密码哈希的步骤

1. 调整数据库密码字段长度

BCRYPT哈希后的密码固定为60字符,需将employee表的em_password字段类型修改为VARCHAR(255),预留足够冗余避免截断。

2. 修改密码存储逻辑(注册/重置场景)

所有涉及密码写入数据库的操作,都要先对明文密码生成BCRYPT哈希:

注册场景(调用insertUser前)

在处理注册的控制器代码中添加哈希处理:

// 获取明文密码
$plain_password = $this->input->post('password');
// 生成BCRYPT哈希
$hashed_password = password_hash($plain_password, PASSWORD_BCRYPT);
// 替换数据中的明文密码
$data['em_password'] = $hashed_password;
// 存入数据库
$this->login_model->insertUser($data);

密码重置场景(更新UpdatePassword方法)

在Login_model.php中自动对重置密码哈希:

public function UpdatePassword($key,$data){
    // 若数据包含明文密码,先哈希处理
    if(isset($data['password'])){
        $data['password'] = password_hash($data['password'], PASSWORD_BCRYPT);
    }
    $this->db->where('forgotten_code',$key);
    $this->db->update('users',$data);       
}

3. 重构登录验证逻辑

放弃原有的明文密码匹配逻辑,改为先查询用户信息,再验证哈希:

修改Login.php的validate_login方法

function validate_login($email = '', $password = '') {
    // 仅根据邮箱和状态查询用户,不包含密码
    $credential = array('em_email' => $email, 'status' => 'ACTIVE');
    $query = $this->login_model->getUserForLogin($credential);
    
    if ($query->num_rows() > 0) {
        $row = $query->row();
        // 用PHP原生函数验证密码哈希是否匹配
        if(password_verify($password, $row->em_password)){
            // 设置登录会话
            $this->session->set_userdata('user_login_access', '1');
            $this->session->set_userdata('user_login_id', $row->em_id);
            $this->session->set_userdata('name', $row->first_name);
            $this->session->set_userdata('email', $row->em_email);
            $this->session->set_userdata('user_image', $row->em_image);
            $this->session->set_userdata('user_type', $row->em_role);
            return 'success';
        }
    }
    // 验证失败返回false
    return false;
}

模型Login_model.php的getUserForLogin方法无需修改,仅负责查询用户基础信息。

4. 修复“记住密码”的安全漏洞

原代码将明文密码存入Cookie存在严重风险,改为存储加密后的用户标识:

修改Login_Auth中的记住密码逻辑

if ($login_status == 'success') {
    $row = $this->login_model->getUserForLogin(array('em_email' => $email))->row();
    if($remember){
        // 加载CI加密库,加密用户ID
        $this->load->library('encryption');
        $encrypted_id = $this->encryption->encrypt($row->em_id);
        // 存储加密后的用户ID和邮箱到Cookie
        setcookie('email', $email, time() + (86400 * 30), "/");
        setcookie('user_id', $encrypted_id, time() + (86400 * 30), "/");
    } else {
        // 清除Cookie
        if(isset($_COOKIE['email'])) setcookie('email',' ', time() - 3600, "/");
        if(isset($_COOKIE['user_id'])) setcookie('user_id',' ', time() - 3600, "/");
    }
    redirect(base_url() . 'dashboard');
}

添加自动登录逻辑(在index方法中)

public function index()
{
    if ($this->session->userdata('user_login_access') == 1){
        redirect(base_url() . 'dashboard');
    }
    // 检查Cookie实现自动登录
    if(isset($_COOKIE['email']) && isset($_COOKIE['user_id'])){
        $this->load->library('encryption');
        try {
            $user_id = $this->encryption->decrypt($_COOKIE['user_id']);
            $user = $this->login_model->getUserById($user_id);
            if($user){
                // 设置会话并跳转
                $this->session->set_userdata('user_login_access', '1');
                $this->session->set_userdata('user_login_id', $user->em_id);
                $this->session->set_userdata('name', $user->first_name);
                $this->session->set_userdata('email', $user->em_email);
                $this->session->set_userdata('user_image', $user->em_image);
                $this->session->set_userdata('user_type', $user->em_role);
                redirect(base_url() . 'dashboard');
            }
        } catch(Exception $e){
            // 解密失败,清除Cookie
            setcookie('email',' ', time() - 3600, "/");
            setcookie('user_id',' ', time() - 3600, "/");
        }
    }
    $data=array();
    $this->load->view('login');
}

模型新增getUserById方法

在Login_model.php中添加:

public function getUserById($user_id){           
    return $this->db->get_where('employee', array('em_id' => $user_id))->row();
}

5. 配置CI加密库(可选但推荐)

使用加密库时,需在config.php中设置安全随机密钥:

$config['encryption_key'] = '你的随机安全密钥';

内容的提问来源于stack exchange,提问作者user15136883

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:07:04