From 5387bdb4b9cf97db571afedb3429d084bff5a40f Mon Sep 17 00:00:00 2001 From: leo <342377760@qq.com> Date: Thu, 4 Mar 2021 13:19:16 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E5=90=8E=E5=8F=B0?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=20=E8=B0=B7=E6=AD=8C=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/admin/controller/Base.php | 71 ++++++ application/admin/controller/Index.php | 5 +- application/admin/controller/Login.php | 79 +++++- application/admin/view/index.html | 121 +++++++++ application/admin/view/login/index.html | 110 +++++++- application/config.php | 9 +- composer.json | 2 +- extend/PHPGangsta/GoogleAuthenticator.php | 297 ++++++++++++++++++++++ public/.htaccess | 13 +- public/static/admin/js/qrcode.min.js | 1 + sql/2021-03-03.sql | 8 + 11 files changed, 699 insertions(+), 17 deletions(-) create mode 100644 extend/PHPGangsta/GoogleAuthenticator.php create mode 100644 public/static/admin/js/qrcode.min.js create mode 100644 sql/2021-03-03.sql diff --git a/application/admin/controller/Base.php b/application/admin/controller/Base.php index ba09c9e..6184295 100644 --- a/application/admin/controller/Base.php +++ b/application/admin/controller/Base.php @@ -5,6 +5,7 @@ */ namespace app\admin\controller; +use PHPGangsta\GoogleAuthenticator; use think\Controller; use Repository\IpRepository; @@ -17,6 +18,12 @@ class Base extends Controller public $role_name = ''; public $admin_id = ''; public $group_name = ''; + /** + * google 二次验证码长度 + * @var int + */ + protected $googleAuthSecretLength = 64; + public function _initialize() { // $ipAccess = (new IpRepository)->ipAccess(); @@ -216,4 +223,68 @@ class Base extends Controller { return $table.'_'.($uid % config('chat_table_num')); } + + // 创建二次验证秘钥 + public function make_google_auth_secret () + { + $ga = new GoogleAuthenticator(); + $key = $ga->createSecret($this->googleAuthSecretLength); + $content = $ga->getQrContent($this->request->host(),$key,session('user_name').'['.date('Y-m-d H:i:s').']'); + if (isset($key)){ + return json(['code' => 1, 'key' => $key, 'qrcode_url' => $content, 'msg' => '获取成功']); + } + + return json(['code' => 0, 'key' => null, 'qrcode_url' => null, 'msg' => '获取失败']); + } + + // 谷歌验证 + public function bind_google_auth () + { + if (request()->isPost()) { + $param = input('post.'); + + if (empty($param['new_google_auth'])) { + return json(['code' => -2, 'data' => '', 'msg' => '请输入验证码']); + } + + if (empty($param['key'])) { + return json(['code' => -2, 'data' => '', 'msg' => '请重试']); + } + $old = isset($param['old_google_auth']) ? $param['old_google_auth'] : null; + $code = isset($param['new_google_auth']) ? $param['new_google_auth'] : null; + $secret = $param['key']; + + $google_secret = null; + $admin_id = session('user_id'); + if ($admin_id) { + $google_secret = db('admins')->where(['id' => session('user_id')])->value('google_secret'); + } + if ($google_secret && strlen($google_secret) == $this->googleAuthSecretLength) { + if (empty($param['old_google_auth'])) { + return json(['code' => -2, 'data' => '', 'msg' => '请输入旧验证码']); + } + //先验证老的 + $ga = new GoogleAuthenticator(); + if(!$ga->verifyCode($google_secret, strval($old))){ + return json(['code' => -2, 'data' => '', 'msg' => '旧验证码验证失败']); + } + if (!$ga->verifyCode($secret,$code)){ + return json(['code' => -2, 'data' => '', 'msg' => '验证码验证失败']); + } + //验证新的 + if (db('admins')->where(['id' => session('user_id')])->update(['google_secret' => $secret])){ + return json(['code' => 1, 'data' => '', 'msg' => '绑定成功']); + } + } else { + $ga = new GoogleAuthenticator(); + if (!$ga->verifyCode($secret,$code)){ + return json(['code' => -2, 'data' => '', 'msg' => '验证码验证失败']); + } + //验证新的 + if (db('admins')->where(['id' => session('user_id')])->update(['google_secret' => $secret])){ + return json(['code' => 1, 'data' => '', 'msg' => '绑定成功']); + } + } + } + } } diff --git a/application/admin/controller/Index.php b/application/admin/controller/Index.php index e1d952f..0c7ea82 100644 --- a/application/admin/controller/Index.php +++ b/application/admin/controller/Index.php @@ -14,7 +14,7 @@ class Index extends Base { // 获取管理员相关数据信息 $uid = session('user_id'); - $admin_data = db('admins')->field('user_avatar')->where('id', $uid)->find(); + $admin_data = db('admins')->field('user_avatar, google_secret')->where('id', $uid)->find(); // 获取管理员的权限 $menu_list = $this->getAdminMeunList(); $pay_money = 0; @@ -33,6 +33,9 @@ class Index extends Base 'menu_two' => $menu_list['menu_two'], 'role_name' => session('role_name'), 'pay_money' => $pay_money, + 'ga_android' => config('ga_android'), + 'ga_ios' => config('ga_ios'), + 'google_secret' => $admin_data['google_secret'] ? 1 : 0, ]); return $this->fetch('/index'); diff --git a/application/admin/controller/Login.php b/application/admin/controller/Login.php index 32c1de2..bb1dcd4 100644 --- a/application/admin/controller/Login.php +++ b/application/admin/controller/Login.php @@ -6,12 +6,24 @@ namespace app\admin\controller; +use PHPGangsta\GoogleAuthenticator; use think\Controller; use Repository\LogRepository; use Repository\IpRepository; class Login extends Controller { + /** + * google 二次验证码长度 + * @var int + */ + protected $googleAuthSecretLength = 64; + /** + * google 二次验证码超时时间 + * @var int + */ + protected $googleAuthTimeout = 300; + // 登录首页 public function index() { @@ -21,6 +33,8 @@ class Login extends Controller // } $this->assign([ 'version' => config('version'), + 'ga_android' => config('ga_android'), + 'ga_ios' => config('ga_ios'), ]); return $this->fetch(); @@ -42,6 +56,16 @@ class Login extends Controller if (empty($userInfo) || !password_verify($password, $userInfo['password']) || 1 != $userInfo['status']) { return json(['code' => -4, 'data' => '', 'msg' => '密码错误']); } + $token = null; + if (isset($userInfo['google_secret']) && strlen($userInfo['google_secret']) == $this->googleAuthSecretLength) { + $token = md5(time().$userInfo['id']); + $redis = new \Redis(); + $redis->connect(config('cache.host'),config('cache.port')); + $redis->auth(config('cache.password')); + $info = ['user_id'=>$userInfo['id'], 'user_name'=>$userInfo['user_name']]; + $redis->set($token, json_encode($info), $this->googleAuthTimeout); + return json(['code' => 1, 'token' => $token, 'msg' => '请输入谷歌验证码']); + } // 记录管理员状态 session('user_name', $userName); @@ -64,7 +88,7 @@ class Login extends Controller ]; db('admins')->where('id', $userInfo['id'])->update($param); LogRepository::write('系统管理', '登录成功'); - return json(['code' => 1, 'data' => url('index/index'), 'msg' => '登录成功']); + return json(['code' => 1, 'data' => url('index/index'), 'token' => $token, 'msg' => '登录成功']); } } @@ -77,4 +101,57 @@ class Login extends Controller $this->redirect(url('login/index')); } + + public function google_auth () + { + if (request()->isPost()) { + $google_auth = input('param.google_auth'); + $token = input('param.token'); + + if (empty($google_auth)) { + return json(['code' => -1, 'data' => '', 'msg' => '谷歌验证码不能为空']); + } + + if (empty($token)) { + return json(['code' => -1, 'data' => '', 'msg' => '参数错误']); + } + + $redis = new \Redis(); + $redis->connect(config('cache.host'),config('cache.port')); + $redis->auth(config('cache.password')); + $userInfo = $redis->get($token); + if ($userInfo) { + $userInfo = json_decode($userInfo, true); + $ga = new GoogleAuthenticator(); + $google_secret = db('admins')->where('id', $userInfo['user_id'])->value('google_secret'); + if($ga->verifyCode($google_secret, $google_auth)){ + // 记录管理员状态 + session('user_name', $userInfo['user_name']); + session('user_id', $userInfo['user_id']); + session('user_last_login', time()); + // 管理员角色 + $role = db('admin_role') + ->alias('a') + ->where('admin_id', $userInfo['user_id']) + ->join('role r',"r.id=a.role_id") + ->field('name') + ->find(); + $role_name = $role['name'] ? $role['name'] : '暂无角色'; + session('role_name', $role_name); + + // 更新管理员状态 + $param = [ + 'last_login_ip' => request()->ip(), + 'last_login_time' => time(), + ]; + db('admins')->where('id', $userInfo['user_id'])->update($param); + LogRepository::write('系统管理', '校验成功'); + return json(['code' => 1, 'data' => url('index/index'), 'token' => $token, 'msg' => '校验成功']); + } + } + + return json(['code' => -1, 'data' => '', 'msg' => '校验失败']); + } + + } } diff --git a/application/admin/view/index.html b/application/admin/view/index.html index 3e0a8b4..c4a3e28 100644 --- a/application/admin/view/index.html +++ b/application/admin/view/index.html @@ -42,6 +42,9 @@