Przeglądaj źródła

会员、管理登录失败多次预警

kevin_zhangl 2 lat temu
rodzic
commit
58fbe209b7

+ 23 - 0
backendApi/modules/v1/models/LoginForm.php

@@ -2,6 +2,7 @@
 namespace backendApi\modules\v1\models;
 
 use common\components\Model;
+use common\helpers\DingTalk;
 use common\libs\LoginIpChecker;
 use Yii;
 use yii\base\Exception;
@@ -20,6 +21,8 @@ class LoginForm extends Model {
 
     const ERROR_IS_MODIFY_PASSWORD = 'ERROR_IS_MODIFY_PASSWORD';
 
+    const BACKEND_LOGIN_FAIL_TIMES = 'backend:loginFail:times_%s';
+
     /**
      * @inheritdoc
      */
@@ -85,6 +88,23 @@ class LoginForm extends Model {
             'FAIL_NUMS' => 1,
         ], 'ADMIN_NAME=:ADMIN_NAME', ['ADMIN_NAME' => $this->adminName]);
         $transaction->commit();
+
+        $cacheKey = sprintf(self::BACKEND_LOGIN_FAIL_TIMES, $this->adminName);
+        Yii::$app->tokenRedis->incr($cacheKey);
+
+        // 连续登录失败次数
+        $loginFailTimes = (int)Yii::$app->tokenRedis->get($cacheKey);
+        // 连续登录失败次数上限
+        $loginFailedTopLimit = (int)Yii::$app->params['backendLoginFailedTimesTopLimit'];
+        if ($loginFailTimes >= $loginFailedTopLimit) {
+            // 发送钉钉提醒
+            $content = [
+                'env' => 'backend',
+                'message' => sprintf('(NG)提醒:管理员[%s]连续登录失败%d次', $this->adminName, $loginFailTimes),
+            ];
+            DingTalk::sendNotice($content);
+        }
+
         if(isset($this->_user)){
             AdminLoginLogger::fail($this->_user,$returnResult);
         }
@@ -94,6 +114,9 @@ class LoginForm extends Model {
      * 更新成功次数
      */
     private function _updateSuccessTimes(){
+        $cacheKey = sprintf(self::BACKEND_LOGIN_FAIL_TIMES, $this->adminName);
+        Yii::$app->tokenRedis->del($cacheKey);
+
         Admin::updateAllCounters([
             'LOGIN_NUMS' => 1,
         ], 'ADMIN_NAME=:ADMIN_NAME', ['ADMIN_NAME' => $this->adminName]);

+ 2 - 0
common/config/params.php

@@ -11,6 +11,8 @@ return [
     'user.passwordResetTokenExpire' => 3600,
     'operationTimeOut' => 60 * 60 * 24,     // 这里设置的15分钟超时
     'pageSize' => 20,
+    'frontendLoginFailedTimesTopLimit' => 10,   // 会员端连续登录失败次数上限
+    'backendLoginFailedTimesTopLimit'  => 10,   // 管理端连续登录失败次数上限
     'http' => [
         'shopApi' => [
             'authKey' => 'sErypUtORfuloNdiTYLINArdtHErSAnDkiRPRElTaiNgIneUSEardopEnTAcErNO',

+ 2 - 2
common/helpers/DingTalk.php

@@ -16,8 +16,8 @@ class DingTalk
         curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         // 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
-         curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
-         curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
+        curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
+        curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
         $data = curl_exec($ch);
         curl_close($ch);
 

+ 14 - 0
frontendApi/modules/v1/models/LoginForm.php

@@ -3,6 +3,7 @@ namespace frontendApi\modules\v1\models;
 
 use common\components\Model;
 use common\helpers\Date;
+use common\helpers\DingTalk;
 use common\libs\LoginIpChecker;
 use common\models\BaUser;
 use common\models\BaUserInfo;
@@ -97,6 +98,19 @@ class LoginForm extends Model
         $cacheKey = sprintf(self::FRONTEND_LOGIN_FAIL_TIMES, $this->userName);
         Yii::$app->tokenRedis->incr($cacheKey);
 
+        // 连续登录失败次数
+        $frontendLoginFailTimes = (int)Yii::$app->tokenRedis->get($cacheKey);
+        // 连续登录失败次数上限
+        $loginFailedTopLimit = (int)Yii::$app->params['frontendLoginFailedTimesTopLimit'];
+        if ($frontendLoginFailTimes >= $loginFailedTopLimit) {
+            // 发送钉钉提醒
+            $content = [
+                'env' => 'frontend',
+                'message' => sprintf('(NG)提醒:会员[%s]连续登录失败%d次', $this->userName, $frontendLoginFailTimes),
+            ];
+            DingTalk::sendNotice($content);
+        }
+
         if(isset($this->_user)){
             UserLoginLogger::fail($this->_userInfo,$returnResult);
         }