Selaa lähdekoodia

后台登录添加验证码

Tree 2 viikkoa sitten
vanhempi
sitoutus
0da4c904d5

+ 50 - 0
app/Http/Controllers/Admin/AdministratorController.php

@@ -469,6 +469,50 @@ class AdministratorController extends Controller
         return view('admin.login');
     }
 
+    /**
+     * 后台登录图形验证码(GD)
+     */
+    public function loginCaptcha(Request $request)
+    {
+        if (!function_exists('imagecreatetruecolor')) {
+            abort(503, 'GD extension required');
+        }
+
+        $chars = '23456789ABCDEFGHJKLMNPQRSTUVWXY';
+        $code = '';
+        $len = strlen($chars) - 1;
+        for ($i = 0; $i < 4; $i++) {
+            $code .= $chars[random_int(0, $len)];
+        }
+        $request->session()->put('admin_login_captcha', strtolower($code));
+
+        $w = 120;
+        $h = 42;
+        $im = imagecreatetruecolor($w, $h);
+        $bg = imagecolorallocate($im, 248, 249, 250);
+        imagefilledrectangle($im, 0, 0, $w, $h, $bg);
+        for ($i = 0; $i < 5; $i++) {
+            $lineColor = imagecolorallocate($im, random_int(180, 230), random_int(180, 230), random_int(180, 230));
+            imageline($im, random_int(0, $w), random_int(0, $h), random_int(0, $w), random_int(0, $h), $lineColor);
+        }
+        for ($i = 0; $i < 50; $i++) {
+            $px = imagecolorallocate($im, random_int(150, 200), random_int(150, 200), random_int(150, 200));
+            imagesetpixel($im, random_int(0, $w - 1), random_int(0, $h - 1), $px);
+        }
+        $textColor = imagecolorallocate($im, random_int(40, 90), random_int(40, 90), random_int(40, 90));
+        imagestring($im, 5, 32, 13, $code, $textColor);
+
+        ob_start();
+        imagepng($im);
+        imagedestroy($im);
+        $png = ob_get_clean();
+
+        return response($png, 200)
+            ->header('Content-Type', 'image/png')
+            ->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
+            ->header('Pragma', 'no-cache');
+    }
+
     public function checkLogin(Request $request)
     {
         $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 5); //只取前4位,这样只判断最优先的语言。如果取前5位,可能出现en,zh的情况,影响判断。
@@ -486,6 +530,12 @@ class AdministratorController extends Controller
             return $this->json(500, trans('cs.login.notice_pass'));
         }
 
+        $captchaInput = isset($post['captcha']) ? strtolower(trim((string) $post['captcha'])) : '';
+        $captchaSession = (string) $request->session()->pull('admin_login_captcha', '');
+        if ($captchaInput === '' || $captchaSession === '' || !hash_equals($captchaSession, $captchaInput)) {
+            return $this->json(500, trans('cs.login.wrong_captcha'));
+        }
+
         $admin = AdminUser::where('account', $post['account'])->first();
 
         if (empty($admin) || $admin->type != 1) {

+ 4 - 0
resources/lang/en_US/cs.php

@@ -25,6 +25,10 @@ return [
         'title' => 'Login',
         'notice_user' => '请输入账号!',
         'notice_pass' => '请输入密码!',
+        'notice_captcha' => 'Please enter the verification code!',
+        'wrong_captcha' => 'Invalid or expired code. Refresh and try again.',
+        'captcha_placeholder' => 'Verification code',
+        'captcha_refresh' => 'Click to refresh',
         'cannotfinduser' => '账号不存在!',
         'wrongpass' => '密码输入不正确!',
         'block' => '账号已被禁用!',

+ 4 - 0
resources/lang/zh_CN/cs.php

@@ -26,6 +26,10 @@ return [
         'title' => '登录',
         'notice_user' => '请输入账号!',
         'notice_pass' => '请输入密码!',
+        'notice_captcha' => '请输入验证码!',
+        'wrong_captcha' => '验证码错误或已过期,请刷新后重试!',
+        'captcha_placeholder' => '验证码',
+        'captcha_refresh' => '点击刷新',
         'cannotfinduser' => '账号不存在!',
         'wrongpass' => '密码输入不正确!',
         'block' => '账号已被禁用!',

+ 22 - 0
resources/views/admin/login.blade.php

@@ -29,6 +29,16 @@
                 <div class="form-group">
                   <input type="password" class="form-control form-control-lg" id="password" placeholder="{{trans('cs.login.notice_pass')}}">
                 </div>
+                <div class="form-group">
+                  <div class="input-group">
+                    <input type="text" class="form-control form-control-lg" id="captcha" name="captcha" autocomplete="off" maxlength="6" placeholder="{{ trans('cs.login.captcha_placeholder') }}">
+                    <div class="input-group-append">
+                      <span class="input-group-text p-0 border-0 bg-transparent" style="cursor:pointer;" onclick="refreshCaptcha()" title="{{ trans('cs.login.captcha_refresh') }}">
+                        <img id="captcha-img" src="/admin/login_captcha" alt="captcha" style="height:48px;border-radius:4px;">
+                      </span>
+                    </div>
+                  </div>
+                </div>
 
                 <div class="mb-2">
                   <button type="button" onclick="login()" class="btn btn-gradient-info btn-lg btn-block">
@@ -62,16 +72,26 @@
         }
     }
 
+    function refreshCaptcha(){
+        $('#captcha-img').attr('src', '/admin/login_captcha?t=' + Date.now());
+    }
+
     function login(){
         var account = $("#account").val();
         var password = $("#password").val();
+        var captcha = $("#captcha").val();
         if(!account || !password){
             layer.msg('账号和密码不能为空', function(){});
             return false;
         }
+        if(!captcha){
+            layer.msg(@json(trans('cs.login.notice_captcha')), function(){});
+            return false;
+        }
         var data = {
             'account':account,
             'password':password,
+            'captcha':captcha,
         };
         myRequest("/admin/login_op","post",data,function(res){
             if(res.code == '200'){
@@ -81,6 +101,8 @@
                 },1500)
             }else{
                 layer.msg(res.msg)
+                refreshCaptcha();
+                $("#captcha").val('');
             }
         });
     }

+ 1 - 0
routes/web.php

@@ -876,6 +876,7 @@ Route::group([
 //    game/admin_background/operate/login
     // 登录
     $route->get('admin/login_op', 'Admin\AdministratorController@login');
+    $route->get('admin/login_captcha', 'Admin\AdministratorController@loginCaptcha');
     $route->post('admin/login_op', 'Admin\AdministratorController@checkLogin');
     $route->get('admin/login_mx', 'Admin\AdministratorController@login');
     $route->post('admin/login_mx', 'Admin\AdministratorController@checkLogin');