Browse Source

修改验证码生成

liuchanglan 4 years ago
parent
commit
7b4db4fc31

+ 6 - 9
src/main/java/com/gz/controller/system/AuthController.java

@@ -1,8 +1,6 @@
 package com.gz.controller.system;
 
-import com.gz.core.annotation.TraceLog;
 import com.gz.core.exception.BusinessException;
-import com.gz.dto.system.MenuDTO;
 import com.gz.jwt.JwtPayload;
 import com.gz.rvo.system.InitialHomeRVO;
 import com.gz.rvo.system.LoginRVO;
@@ -13,7 +11,6 @@ import com.gz.vo.system.UpdatePasswordVO;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
-import java.util.List;
 
 /**
  * 登录授权控制器
@@ -28,6 +25,7 @@ public class AuthController {
     private AuthService authService;
 
     @PostMapping("login")
+//    @TraceLog(module = "登录授权模块",business = "用户登录")
     public LoginRVO login(@RequestBody LoginVO loginVO) throws BusinessException, NoSuchMethodException {
         return authService.login(loginVO);
     }
@@ -61,13 +59,12 @@ public class AuthController {
     }
 
     /**
-     * @description 获取有权限的按钮
+     * @description 生成验证码
      * @author LiuChangLan
-     * @since 2020/9/25 15:43
+     * @since 2021/2/22 18:00
      */
-    @GetMapping("getLoginButtons")
-    public List<MenuDTO> getLoginButtons(Integer menuId){
-        return authService.getLoginButtons(menuId);
+    @GetMapping("generatePictureCaptcha")
+    public String generatePictureCaptcha(){
+        return authService.generatePictureCaptcha();
     }
-
 }

+ 1 - 0
src/main/java/com/gz/core/exception/CustomExceptionEnum.java

@@ -16,6 +16,7 @@ public enum CustomExceptionEnum implements CustomResponsInterface {
     ACCOUNT_OR_PASSWORD_INCORRECT(1000,"用户名不存在、或者密码不正确!"),
     ACCOUNT_DISABLE(1001,"用户已禁用"),
     LOGIN_TIMEOUT(1002,"登录已过期"),
+    CAPTCHA_ERROR(1003,"验证码错误"),
     DICT_CODE_EXISTS(1004,"字典编码已存在,请更换"),
     File_NOT_EXISTS(1005,"请选择一个文件"),
     PASSWORD_NO_INCORRECT(1006,"密码不正确");

+ 1 - 0
src/main/java/com/gz/service/system/AuthService.java

@@ -49,4 +49,5 @@ public interface AuthService {
 
     List<MenuDTO> getLoginButtons(Integer menuId);
 
+    String generatePictureCaptcha();
 }

+ 20 - 1
src/main/java/com/gz/service/system/impl/AuthServiceImpl.java

@@ -1,5 +1,7 @@
 package com.gz.service.system.impl;
 
+import cn.hutool.captcha.CaptchaUtil;
+import cn.hutool.captcha.LineCaptcha;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.tree.Tree;
 import cn.hutool.core.lang.tree.TreeNodeConfig;
@@ -28,6 +30,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -49,11 +53,18 @@ public class AuthServiceImpl implements AuthService {
     @Resource
     private MenuMapper menuMapper;
 
+    @Resource
+    private HttpServletRequest request;
+
     @Override
     public LoginRVO login(LoginVO vo) {
+        // 后台存储的验证码
+        String serverCaptcha = String.valueOf(request.getSession().getAttribute("captcha"));
+        if (!vo.getCaptcha().equals(serverCaptcha)){
+            throw new BusinessException(CustomExceptionEnum.CAPTCHA_ERROR);
+        }
         // 查询用户参数
         AdminDTO param = new AdminDTO();
-
         // 根据用户名查
         param.setAccount(vo.getAccount());
         AdminDTO loginDTO = adminMapper.selectOne(param);
@@ -198,4 +209,12 @@ public class AuthServiceImpl implements AuthService {
         return menuMapper.getRoleButtle(JwtUtils.getCurrentUserJwtPayload().getRoleId(),menuId);
     }
 
+    @Override
+    public String generatePictureCaptcha() {
+        HttpSession session = request.getSession();
+        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
+        session.setAttribute("captcha",lineCaptcha.getCode());
+        log.info("生成验证码:{}",lineCaptcha.getCode());
+        return "data:image/jpg;base64," + lineCaptcha.getImageBase64();
+    }
 }

+ 2 - 0
src/main/java/com/gz/vo/system/LoginVO.java

@@ -13,4 +13,6 @@ public class LoginVO {
     private String account;
     // 密码
     private String password;
+    // 验证码
+    private String captcha;
 }

+ 1 - 1
src/main/resources/application.yml

@@ -22,5 +22,5 @@ auth:
     # 进行登录验证的地址
     force-urls: /**
     # 跳过验证地址
-    skip-urls: /,/**/*.png,/**/*.jpg,/**/*.html,/**/*.ico,/**/*.css,/**/*.js,/webSocket/**,/**/*.woff2,/system/auth/login,/system/auth/refreshToken
+    skip-urls: /,/**/*.png,/**/*.jpg,/**/*.html,/**/*.ico,/**/*.css,/**/*.js,/webSocket/**,/**/*.woff2,/system/auth/login,/system/auth/refreshToken,/system/auth/generatePictureCaptcha
 

BIN
src/main/resources/static/images/bg.png


BIN
src/main/resources/static/images/captcha.jpg


+ 77 - 167
src/main/resources/static/login.html

@@ -9,11 +9,12 @@
     <meta name="apple-mobile-web-app-status-bar-style" content="black">
     <meta name="apple-mobile-web-app-capable" content="yes">
     <meta name="format-detection" content="telephone=no">
-    <link rel="stylesheet" href="lib/layui-v2.5.5/css/layui.css" media="all">
-<!--    &lt;!&ndash;[if lt IE 9]>-->
-<!--    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>-->
-<!--    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>-->
-<!--    <![endif]&ndash;&gt;-->
+    <link rel="icon" href="images/favicon.ico">
+    <link rel="stylesheet" href="../lib/layui-v2.5.5/css/layui.css" media="all">
+    <!--[if lt IE 9]>
+    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
+    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
+    <![endif]-->
     <style>
         html, body {
             width: 100%;
@@ -22,24 +23,7 @@
         }
 
         body {
-            /*background: #0C3A79;*/
-            background-image: url("./images/loginBg.png");
-            margin: 0;
-            padding: 0;
-            background-size: cover;
-            background-repeat: no-repeat;
-        }
-
-        .admin-login-background {
-            margin: 0 auto;
-            margin-top: 20px;
-            width: 360px;
-            height: 300px;
-            /*position: absolute;*/
-            /*left: 50%;*/
-            /*top: 40%;*/
-            /*margin-left: -180px;*/
-            /*margin-top: -100px;*/
+            background: #1E9FFF;
         }
 
         body:after {
@@ -65,6 +49,16 @@
             overflow: hidden
         }
 
+        .admin-login-background {
+            width: 360px;
+            height: 300px;
+            position: absolute;
+            left: 50%;
+            top: 40%;
+            margin-left: -180px;
+            margin-top: -100px;
+        }
+
         .logo-title {
             text-align: center;
             letter-spacing: 2px;
@@ -75,18 +69,14 @@
             color: #1E9FFF;
             font-size: 25px;
             font-weight: bold;
-            text-shadow:10px 10px 10px red;
         }
 
         .login-form {
-            /*background-color: #fff;*/
-            /*border: 1px solid #fff;*/
-            /*border-radius: 3px;*/
+            background-color: #fff;
+            border: 1px solid #fff;
+            border-radius: 3px;
             padding: 14px 20px;
-            /*box-shadow: 0 0 8px #eeeeee;*/
-            /*margin-top: 150%;*/
-            position: absolute;
-            bottom: 0%;
+            box-shadow: 0 0 8px #eeeeee;
         }
 
         .login-form .layui-form-item {
@@ -107,30 +97,6 @@
             padding-left: 36px;
         }
 
-        .captcha-img img {
-            height: 34px;
-            border: 1px solid #e6e6e6;
-            height: 36px;
-            width: 100%;
-        }
-        .bg h1{
-            text-align: center;
-            font-weight: 900;
-            color: #1660B9;
-            text-shadow: 4px 4px 7px #FFF;
-            margin-top: 450px;
-        }
-        .logo{
-            width: 150px;
-            height: 100px;
-            background-image: url("./images/login_logo.png");
-            background-repeat:no-repeat;
-            background-size:cover;
-        }
-        .layui-container{
-            padding: 0;
-        }
-
         .captcha {
             width: 60%;
             display: inline-block;
@@ -148,21 +114,20 @@
             height: 36px;
             width: 100%;
         }
-
-        #captchaPic{
-            cursor: pointer;
-        }
     </style>
 </head>
 <body>
 <div class="layui-container">
     <div class="admin-login-background">
-        <div class="layui-form login-form">
+        <div class="layui-form login-form" lay-filter="login-form">
             <form class="layui-form" action="">
+                <div class="layui-form-item logo-title">
+                    <h1>廉政档案系统</h1>
+                </div>
                 <div class="layui-form-item">
                     <label class="layui-icon layui-icon-username"></label>
                     <input type="text" name="account" lay-verify="required|account" placeholder="用户名或者邮箱"
-                           autocomplete="off" class="layui-input" value="admin">
+                           autocomplete="off" class="layui-input" value="">
                 </div>
                 <div class="layui-form-item">
                     <label class="layui-icon layui-icon-password"></label>
@@ -173,11 +138,14 @@
                     <label class="layui-icon layui-icon-vercode"></label>
                     <input type="text" name="captcha" lay-verify="required|captcha" placeholder="图形验证码"
                            autocomplete="off" class="layui-input verification captcha" value="">
-                    <div class="captcha-img">
-                            <canvas id="captchaPic" width="108" height="38"></canvas>
+                    <div class="captcha-img" style="cursor:pointer">
+                        <img id="captchaPic">
                     </div>
                 </div>
-                <div class="layui-form-item" style="margin-top: 30px">
+                <div class="layui-form-item">
+                    <input type="checkbox" id="rememberMe" name="rememberMe" value="" lay-skin="primary" title="记住密码">
+                </div>
+                <div class="layui-form-item">
                     <button class="layui-btn layui-btn layui-btn-normal layui-btn-fluid" lay-submit=""
                             lay-filter="login">登 入
                     </button>
@@ -197,23 +165,36 @@
             $ = layui.jquery,
             layer = layui.layer;
 
-        var captcha = [];
-
         // 登录过期的时候,跳出ifram框架
         if (top.location != self.location) top.location = self.location;
 
-        // // 粒子线条背景
-        // $(document).ready(function () {
-        //     $('.layui-container').particleground({
-        //         dotColor: '#7ec7fd',
-        //         lineColor: '#7ec7fd'
-        //     });
-        // });
+        // 粒子线条背景
+        $(document).ready(function () {
+            $('.layui-container').particleground({
+                dotColor: '#7ec7fd',
+                lineColor: '#7ec7fd'
+            });
+        });
+
+        let readCachePassword = function (){
+            let a = layui.data('rememberMe')
+            if (a){
+                form.val("login-form", a.data);
+                form.render();
+            }
+        }
+
+        // 生成验证码
+        let generatePictureCaptcha = function () {
+            http.get('system/auth/generatePictureCaptcha', {}, true, res => {
+                $("#captchaPic").prop('src',res.data)
+            })
+        }
 
         // 进行登录操作
         form.on('submit(login)', function (data) {
             data = data.field;
-            if (data.username == '') {
+            if (data.account == '') {
                 layer.msg('用户名不能为空');
                 return false;
             }
@@ -221,107 +202,36 @@
                 layer.msg('密码不能为空');
                 return false;
             }
-            // 正确验证码
-            var captchaCode = captcha.join("");
-            // 用户填写验证码
-            var captchaUser = data.captcha;
-            if (captchaUser == '') {
+            if (data.captcha == '') {
                 layer.msg('验证码不能为空');
                 return false;
             }
-            if (captchaCode.toUpperCase() != captchaUser.toUpperCase()){
-                layer.msg('验证码不正确');
-                // 错误刷新验证码
-                draw(captcha);
-                return false;
-            }
-            http.post('system/auth/login', JSON.stringify(data), false, function (res) {
-                if (res.code != 200) {
-                    layer.msg(res.msg, {
-                        icon: 2
-                    },function () {
-                        console.log('刷新')
-                        draw(captcha);
-                    });
-                } else {
-                    layer.msg('登录成功', {
-                        icon: 1
-                    }, function () {
-                        window.location = 'jump.html';
-                    });
-                }
-            })
 
-            return false;
-        });
-        // 绘制验证码
-        draw(captcha);
-
-        // 点击刷新验证码
-        $(document).on('click','#captchaPic',function(){
-            draw(captcha);
-        });
-
-        /**
-         * 生成验证码
-         */
-        function draw(show_num) {
-            var canvas_width=$('#captchaPic').width();
-            var canvas_height=$('#captchaPic').height();
-            var canvas = document.getElementById("captchaPic");//获取到canvas的对象,演员
-            var context = canvas.getContext("2d");//获取到canvas画图的环境,演员表演的舞台
-            canvas.width = canvas_width;
-            canvas.height = canvas_height;
-            var sCode = "A,B,C,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0";
-            var aCode = sCode.split(",");
-            var aLength = aCode.length;//获取到数组的长度
-
-            for (var i = 0; i <= 3; i++) {
-                var j = Math.floor(Math.random() * aLength);//获取到随机的索引值
-                var deg = Math.random() * 30 * Math.PI / 180;//产生0~30之间的随机弧度
-                var txt = aCode[j];//得到随机的一个内容
-                show_num[i] = txt;
-                var x = 10 + i * 20;//文字在canvas上的x坐标
-                var y = 20 + Math.random() * 8;//文字在canvas上的y坐标
-                context.font = "bold 23px 微软雅黑";
-
-                context.translate(x, y);
-                context.rotate(deg);
-
-                context.fillStyle = randomColor();
-                context.fillText(txt, 0, 0);
-
-                context.rotate(-deg);
-                context.translate(-x, -y);
+            let rememberMe = {
+                account: data.account,
+                password: data.password,
+                rememberMe: $("#rememberMe").prop('checked')
             }
-            for (var i = 0; i <= 5; i++) { //验证码上显示线条
-                context.strokeStyle = randomColor();
-                context.beginPath();
-                context.moveTo(Math.random() * canvas_width, Math.random() * canvas_height);
-                context.lineTo(Math.random() * canvas_width, Math.random() * canvas_height);
-                context.stroke();
+            if (rememberMe.rememberMe) {
+                // 勾选记住密码
+                layui.data('rememberMe', {
+                    key: 'data',
+                    value: rememberMe
+                })
+            }else {
+                layui.data('rememberMe', null)
             }
-            for (var i = 0; i <= 30; i++) { //验证码上显示小点
-                context.strokeStyle = randomColor();
-                context.beginPath();
-                var x = Math.random() * canvas_width;
-                var y = Math.random() * canvas_height;
-                context.moveTo(x, y);
-                context.lineTo(x + 1, y + 1);
-                context.stroke();
-            }
-        }
+            http.login(data)
+            return false;
+        });
 
-        /**
-         * 随机颜色
-         */
-        function randomColor() {//得到随机的颜色值
-            var r = Math.floor(Math.random() * 256);
-            var g = Math.floor(Math.random() * 256);
-            var b = Math.floor(Math.random() * 256);
-            return "rgb(" + r + "," + g + "," + b + ")";
-        }
+        // 点击验证码刷新
+        $("#captchaPic").click(function () {
+            generatePictureCaptcha()
+        })
 
+        readCachePassword()
+        generatePictureCaptcha()
     });
 </script>
 </body>

+ 0 - 200
src/main/resources/static/login12.html

@@ -1,200 +0,0 @@
- <!DOCTYPE html>
-<html>
-<head>
-    <meta charset="UTF-8">
-    <title>后台管理-登陆</title>
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
-    <meta http-equiv="Access-Control-Allow-Origin" content="*">
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
-    <meta name="apple-mobile-web-app-status-bar-style" content="black">
-    <meta name="apple-mobile-web-app-capable" content="yes">
-    <meta name="format-detection" content="telephone=no">
-    <link rel="stylesheet" href="../lib/layui-v2.5.5/css/layui.css" media="all">
-    <!--[if lt IE 9]>
-    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
-    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
-    <![endif]-->
-    <style>
-        html, body {
-            width: 100%;
-            height: 100%;
-            overflow: hidden
-        }
-
-        body {
-            background: #1E9FFF;
-        }
-
-        body:after {
-            content: '';
-            background-repeat: no-repeat;
-            background-size: cover;
-            -webkit-filter: blur(3px);
-            -moz-filter: blur(3px);
-            -o-filter: blur(3px);
-            -ms-filter: blur(3px);
-            filter: blur(3px);
-            position: absolute;
-            top: 0;
-            left: 0;
-            right: 0;
-            bottom: 0;
-            z-index: -1;
-        }
-
-        .layui-container {
-            width: 100%;
-            height: 100%;
-            overflow: hidden
-        }
-
-        .admin-login-background {
-            width: 360px;
-            height: 300px;
-            position: absolute;
-            left: 50%;
-            top: 40%;
-            margin-left: -180px;
-            margin-top: -100px;
-        }
-
-        .logo-title {
-            text-align: center;
-            letter-spacing: 2px;
-            padding: 14px 0;
-        }
-
-        .logo-title h1 {
-            color: #1E9FFF;
-            font-size: 25px;
-            font-weight: bold;
-        }
-
-        .login-form {
-            background-color: #fff;
-            border: 1px solid #fff;
-            border-radius: 3px;
-            padding: 14px 20px;
-            box-shadow: 0 0 8px #eeeeee;
-        }
-
-        .login-form .layui-form-item {
-            position: relative;
-        }
-
-        .login-form .layui-form-item label {
-            position: absolute;
-            left: 1px;
-            top: 1px;
-            width: 38px;
-            line-height: 36px;
-            text-align: center;
-            color: #d2d2d2;
-        }
-
-        .login-form .layui-form-item input {
-            padding-left: 36px;
-        }
-
-        .captcha {
-            width: 60%;
-            display: inline-block;
-        }
-
-        .captcha-img {
-            display: inline-block;
-            width: 34%;
-            float: right;
-        }
-
-        .captcha-img img {
-            height: 34px;
-            border: 1px solid #e6e6e6;
-            height: 36px;
-            width: 100%;
-        }
-    </style>
-</head>
-<body>
-<div class="layui-container">
-    <div class="admin-login-background">
-        <div class="layui-form login-form">
-            <form class="layui-form" action="">
-                <div class="layui-form-item logo-title">
-                    <h1>江宁开发区干部员工电子廉政档案系统</h1>
-                </div>
-                <div class="layui-form-item">
-                    <label class="layui-icon layui-icon-username"></label>
-                    <input type="text" name="account" lay-verify="required|account" placeholder="用户名或者邮箱"
-                           autocomplete="off" class="layui-input" value="admin">
-                </div>
-                <div class="layui-form-item">
-                    <label class="layui-icon layui-icon-password"></label>
-                    <input type="password" name="password" lay-verify="required|password" placeholder="密码"
-                           autocomplete="off" class="layui-input" value="123456">
-                </div>
-                <div class="layui-form-item">
-                    <label class="layui-icon layui-icon-vercode"></label>
-                    <input type="text" name="captcha" lay-verify="required|captcha" placeholder="图形验证码"
-                           autocomplete="off" class="layui-input verification captcha" value="xszg">
-                    <div class="captcha-img">
-                        <img id="captchaPic" src="./images/captcha.jpg">
-                    </div>
-                </div>
-                <div class="layui-form-item">
-                    <input type="checkbox" name="rememberMe" value="true" lay-skin="primary" title="记住密码">
-                </div>
-                <div class="layui-form-item">
-                    <button class="layui-btn layui-btn layui-btn-normal layui-btn-fluid" lay-submit=""
-                            lay-filter="login">登 入
-                    </button>
-                </div>
-            </form>
-        </div>
-    </div>
-</div>
-<script src="./lib/jquery-3.4.1/jquery-3.4.1.min.js" charset="utf-8"></script>
-<script src="./lib/layui-v2.5.5/layui.js" charset="utf-8"></script>
-<script src="./lib/jq-module/jquery.particleground.min.js" charset="utf-8"></script>
-<script src="./js/lay-config.js?v=1.0.4" charset="utf-8"></script>
-<script>
-    layui.use(['form', 'http'], function () {
-        var form = layui.form,
-            http = layui.http,
-            $ = layui.jquery,
-            layer = layui.layer;
-
-        // 登录过期的时候,跳出ifram框架
-        if (top.location != self.location) top.location = self.location;
-
-        // 粒子线条背景
-        $(document).ready(function () {
-            $('.layui-container').particleground({
-                dotColor: '#7ec7fd',
-                lineColor: '#7ec7fd'
-            });
-        });
-
-        // 进行登录操作
-        form.on('submit(login)', function (data) {
-            data = data.field;
-            if (data.username == '') {
-                layer.msg('用户名不能为空');
-                return false;
-            }
-            if (data.password == '') {
-                layer.msg('密码不能为空');
-                return false;
-            }
-            // if (data.captcha == '') {
-            //     layer.msg('验证码不能为空');
-            //     return false;
-            // }
-            http.login(data)
-
-            return false;
-        });
-    });
-</script>
-</body>
-</html>