1、判断表单提交方式是否为POST
if (!$_POST) { return; }
2、判断验证码
// 在安装了gd库时才执行验证码验证 if (extension_loaded("gd") && $this->config('admin_check_code') && strtolower(post('checkcode', 'var')) != session('checkcode')) { json(0, '验证码错误!'); }
3、将用户名、密码赋值给变量
// 就收数据 $username = post('username'); $password = post('password');
4、判断用户名、密码输入
if (!preg_match('/^[x{4e00}-x{9fa5}w-.@]+$/u', $username)) { json(0, '用户名含有不允许的特殊字符!'); } if (!$username) { json(0, '用户名不能为空!'); } if (!$password) { json(0, '密码不能为空!'); }
5、判断当前是否为锁定状态
if (!!$time = $this->checkLoginBlack()) { $this->log('登录锁定!'); json(0, '您登录失败次数太多已被锁定,请' . $time . '秒后再试!'); }
6、判断数据库写入权限
// 判断数据库写入权限 if ((get_db_type() == 'sqlite') && !is_writable(ROOT_PATH . $this->config('database.dbname'))) { json(0, '数据库目录写入权限不足!'); }
7、验证用户名、密码是否正确,若错误,则重新生成验证码
// 执行用户登录 $where = array( 'username' => $username, 'password' => encrypt_string($password) ); if (!!$login = $this->model->login($where)) { xxxxxxxx $this->log('登录成功!'); json(1, url('admin/Index/home')); } else { $this->setLoginBlack(); $this->log('登录失败!'); session('checkcode', mt_rand(10000, 99999)); // 登录失败,随机打乱原有验证码 json(0, '用户名或密码错误!'); }
8、登录成功后,将用户信息以及RBAC等信息写入缓存中
session_regenerate_id(true); session('sid', encrypt_string(session_id() . $login->id)); // 会话标识 session('M', M); session('id', $login->id); // 用户id session('ucode', $login->ucode); // 用户编码 session('username', $login->username); // 用户名 session('realname', $login->realname); // 真实名字 if ($where['password'] != '14e1b600b1fd579f47433b88e8d85291') { session('pwsecurity', true); } session('acodes', $login->acodes); // 用户管理区域 if ($login->acodes) { // 当前显示区域 session('acode', $login->acodes[0]); } else { session('acode', ''); } session('rcodes', $login->rcodes); // 用户角色代码表 session('levels', $login->levels); // 用户权限URL列表 session('menu_tree', $login->menus); // 菜单树 session('area_map', $login->area_map); // 区域代码名称映射表 session('area_tree', $login->area_tree); // 用户区域树
至此,pbootcms后台登录验证的基本逻辑已经完成
以下为完整代码
// 异步登录验证 public function login() { if (!$_POST) { return; } // 在安装了gd库时才执行验证码验证 if (extension_loaded("gd") && $this->config('admin_check_code') && strtolower(post('checkcode', 'var')) != session('checkcode')) { json(0, '验证码错误!'); } // 就收数据 $username = post('username'); $password = post('password'); if (!preg_match('/^[x{4e00}-x{9fa5}w-.@]+$/u', $username)) { json(0, '用户名含有不允许的特殊字符!'); } if (!$username) { json(0, '用户名不能为空!'); } if (!$password) { json(0, '密码不能为空!'); } if (!!$time = $this->checkLoginBlack()) { $this->log('登录锁定!'); json(0, '您登录失败次数太多已被锁定,请' . $time . '秒后再试!'); } // 执行用户登录 $where = array( 'username' => $username, 'password' => encrypt_string($password) ); // 判断数据库写入权限 if ((get_db_type() == 'sqlite') && !is_writable(ROOT_PATH . $this->config('database.dbname'))) { json(0, '数据库目录写入权限不足!'); } if (!!$login = $this->model->login($where)) { session_regenerate_id(true); session('sid', encrypt_string(session_id() . $login->id)); // 会话标识 session('M', M); session('id', $login->id); // 用户id session('ucode', $login->ucode); // 用户编码 session('username', $login->username); // 用户名 session('realname', $login->realname); // 真实名字 if ($where['password'] != '14e1b600b1fd579f47433b88e8d85291') { session('pwsecurity', true); } session('acodes', $login->acodes); // 用户管理区域 if ($login->acodes) { // 当前显示区域 session('acode', $login->acodes[0]); } else { session('acode', ''); } session('rcodes', $login->rcodes); // 用户角色代码表 session('levels', $login->levels); // 用户权限URL列表 session('menu_tree', $login->menus); // 菜单树 session('area_map', $login->area_map); // 区域代码名称映射表 session('area_tree', $login->area_tree); // 用户区域树 $this->log('登录成功!'); json(1, url('admin/Index/home')); } else { $this->setLoginBlack(); $this->log('登录失败!'); session('checkcode', mt_rand(10000, 99999)); // 登录失败,随机打乱原有验证码 json(0, '用户名或密码错误!'); } }
// 检查是否在黑名单 private function checkLoginBlack() { // 读取黑名单 $ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php'; if (file_exists($ip_black)) { $data = require $ip_black; $user_ip = get_user_ip(); $lock_time = $this->config('lock_time') ?: 900; $lock_count = $this->config('lock_count') ?: 5; if (isset($data[$user_ip]) && $data[$user_ip]['count'] >= $lock_count && time() - $data[$user_ip]['time'] < $lock_time) { return $lock_time - (time() - $data[$user_ip]['time']); // 返回剩余秒数 } } return false; }
// 添加登录黑名单 private function setLoginBlack() { // 读取黑名单 $ip_black = RUN_PATH . '/data/' . md5('login_black') . '.php'; if (file_exists($ip_black)) { $data = require $ip_black; } else { $data = array(); } // 添加IP $user_ip = get_user_ip(); $lock_time = $this->config('lock_time') ?: 900; $lock_count = $this->config('lock_count') ?: 5; if (isset($data[$user_ip]) && $data[$user_ip]['count'] < $lock_count && time() - $data[$user_ip]['time'] < $lock_time) { $data[$user_ip] = array( 'time' => time(), 'count' => $data[get_user_ip()]['count'] + 1 ); } else { $data[$user_ip] = array( 'time' => time(), 'count' => 1 ); } // 写入黑名单 check_file($ip_black, true); return file_put_contents($ip_black, "<?php return " . var_export($data, true) . ";"); }