Parcourir la source

将验证码存储改为前端发送指纹码

xusl il y a 2 ans
Parent
commit
8f823aa5b9

+ 12 - 13
backend/src/main/java/com/jiayue/ssi/config/WebSecurityConfig.java

@@ -44,14 +44,16 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     CustomLogoutSuccessHandler customLogoutSuccessHandler;
     @Autowired
     JwtTokenUtil jwtTokenUtil;
-//    @Autowired
-//    XssEscapeFilter xssEscapeFilter;
-//    @Autowired
-//    XssKeywordsFilter xssKeywordsFilter;
-//    @Autowired
-//    SqlFilter sqlFilter;
+    @Autowired
+    XssEscapeFilter xssEscapeFilter;
+    @Autowired
+    XssKeywordsFilter xssKeywordsFilter;
+    @Autowired
+    SqlFilter sqlFilter;
     @Autowired
     InterfaceLimitFilter interfaceLimitFilter;
+    @Autowired
+    VerifySmFilter verifySmFilter;
 
 
     @Bean
@@ -79,13 +81,10 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
     @Override
     protected void configure(HttpSecurity httpSecurity) throws Exception {
         httpSecurity.addFilterBefore(interfaceLimitFilter, LogoutFilter.class);
-//
-//        httpSecurity.addFilterBefore(xssEscapeFilter, LogoutFilter.class);
-//        httpSecurity.addFilterBefore(sqlFilter, LogoutFilter.class);
-        httpSecurity.addFilterBefore(new VerifySmFilter(), LogoutFilter.class);
-        httpSecurity.addFilterBefore(new XssKeywordsFilter(), LogoutFilter.class);
-        httpSecurity.addFilterBefore(new XssEscapeFilter(), LogoutFilter.class);
-        httpSecurity.addFilterBefore(new SqlFilter(), LogoutFilter.class);
+        httpSecurity.addFilterBefore(verifySmFilter, LogoutFilter.class);
+        httpSecurity.addFilterBefore(xssKeywordsFilter, LogoutFilter.class);
+        httpSecurity.addFilterBefore(xssEscapeFilter, LogoutFilter.class);
+        httpSecurity.addFilterBefore(sqlFilter, LogoutFilter.class);
         httpSecurity.addFilterBefore(new VerifyCodeFilter(), LogoutFilter.class);
         httpSecurity.addFilterBefore(new MailCodeFilter(), LogoutFilter.class);
         httpSecurity.addFilterBefore(new JwtAuthenticationTokenFilter(userServiceImpl, jwtTokenUtil), LogoutFilter.class);

+ 5 - 12
backend/src/main/java/com/jiayue/ssi/controller/UserLoginController.java

@@ -1,10 +1,5 @@
 package com.jiayue.ssi.controller;
 
-import cn.hutool.captcha.CaptchaUtil;
-import cn.hutool.captcha.CircleCaptcha;
-import com.jiayue.ssi.annotation.InterfaceLimit;
-import com.jiayue.ssi.annotation.OperateLog;
-import com.jiayue.ssi.backenum.BusinessType;
 import com.jiayue.ssi.config.SendMailUtil;
 import com.jiayue.ssi.constant.CacheConstants;
 import com.jiayue.ssi.constant.CustomException;
@@ -16,14 +11,9 @@ import com.jiayue.ssi.util.*;
 import com.wf.captcha.SpecCaptcha;
 import com.wf.captcha.base.Captcha;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.MimeMessageHelper;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RestController;
-
-import javax.mail.internet.MimeMessage;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -55,7 +45,7 @@ public class UserLoginController {
      * @throws IOException
      */
     @GetMapping("/getVerifyCode")
-    public ResponseVO getVerifyCode(HttpServletResponse httpServletResponse) throws CustomException {
+    public ResponseVO getVerifyCode(String murmur,HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws CustomException {
         // gif类型
         // GifCaptcha captcha = new GifCaptcha(130, 48);
         // 中文类型
@@ -67,6 +57,9 @@ public class UserLoginController {
         // png类型
         // 三个参数分别为宽、高、位数
         try {
+            if (murmur.length()!=32){
+                return ResponseVO.fail("不能生成验证码!");
+            }
             String textcode = "";
             String base64 = "";
             while (true) {
@@ -96,7 +89,7 @@ public class UserLoginController {
             }
 
             String uuid = IdUtils.simpleUUID();
-            String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
+            String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid+murmur;
             // uuid存入缓存,失效时间默认5分钟
             LocalCache.set(verifyKey, textcode);
             // 输出图片流

+ 47 - 54
backend/src/main/java/com/jiayue/ssi/filter/MailCodeFilter.java

@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletResponse;
 
 import com.jiayue.ssi.constant.Constants;
 import com.jiayue.ssi.factory.LoginFactory;
+import com.jiayue.ssi.util.ResponseInfo;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
@@ -20,71 +21,63 @@ import com.jiayue.ssi.util.LocalCache;
 import lombok.RequiredArgsConstructor;
 
 /**
-* 邮箱口令过滤器
-*
-* @author xsl
-* @since 2023/02/20
-*/
+ * 邮箱口令过滤器
+ *
+ * @author xsl
+ * @since 2023/02/20
+ */
 @RequiredArgsConstructor
 @Order(8)
 public class MailCodeFilter extends OncePerRequestFilter {
     private String defaultFilterProcessUrl = "/user/login";
 
-
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
-        if ("POST".equalsIgnoreCase(request.getMethod()) && defaultFilterProcessUrl.equals(request.getServletPath())) {
-            // 是否需要邮箱口令验证
-            if (CacheConstants.use_send_mail) {
-                // 验证码验证
-                String username = request.getParameter("username");
-                Object mailCode = LocalCache.get(CacheConstants.MAIL_CODE_KEY + username);
+        try {
+            if ("POST".equalsIgnoreCase(request.getMethod()) && defaultFilterProcessUrl.equals(request.getServletPath())) {
+                // 是否需要邮箱口令验证
+                if (CacheConstants.use_send_mail) {
+                    // 验证码验证
+                    String username = request.getParameter("username");
+                    Object mailCode = LocalCache.get(CacheConstants.MAIL_CODE_KEY + username);
 
-                // 校验服务端验证码
-                if (mailCode == null || "".equals(mailCode)) {
-                    // 记录用户失败日志
-                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
-                    response.addHeader("Access-Control-Allow-Origin", "*");
-                    response.setContentType("text/html;charset=UTF-8");
-                    response.setStatus(401);
-                    response.getWriter().write("邮箱口令无效,需要重新获取!");
-                    return;
-                }
-                // 页面录入的邮箱口令
-                String mailbox = request.getParameter("mailbox");
+                    // 校验服务端验证码
+                    if (mailCode == null || "".equals(mailCode)) {
+                        // 记录用户失败日志
+                        LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
+                        ResponseInfo.doResponse(response, "邮箱口令无效,需要重新获取!", 401);
+                        return;
+                    }
+                    // 页面录入的邮箱口令
+                    String mailbox = request.getParameter("mailbox");
 
-                // 校验页面验证码
-                if (StringUtils.isEmpty(mailbox)) {
-                    // 记录用户失败日志
-                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
-                    response.addHeader("Access-Control-Allow-Origin", "*");
-                    response.setContentType("text/html;charset=UTF-8");
-                    response.setStatus(401);
-                    response.getWriter().write("非法访问,邮箱口令错误!");
-                    return;
-                }
-                if (mailbox.length() != 6) {
-                    // 记录用户失败日志
-                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
-                    response.addHeader("Access-Control-Allow-Origin", "*");
-                    response.setContentType("text/html;charset=UTF-8");
-                    response.setStatus(401);
-                    response.getWriter().write("需要6位邮箱口令!");
-                    return;
-                }
-                if (!String.valueOf(mailCode).toLowerCase().equals(mailbox.toLowerCase())) {
-                    // 记录用户失败日志
-                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
-                    // 删除缓存邮箱口令
-                    LocalCache.remove(CacheConstants.MAIL_CODE_KEY + username);
-                    response.addHeader("Access-Control-Allow-Origin", "*");
-                    response.setContentType("text/html;charset=UTF-8");
-                    response.setStatus(401);
-                    response.getWriter().write("邮箱口令错误!");
-                    return;
+                    // 校验页面验证码
+                    if (StringUtils.isEmpty(mailbox)) {
+                        // 记录用户失败日志
+                        LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
+                        ResponseInfo.doResponse(response, "非法访问,邮箱口令错误!", 401);
+                        return;
+                    }
+                    if (mailbox.length() != 6) {
+                        // 记录用户失败日志
+                        LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
+                        ResponseInfo.doResponse(response, "需要6位邮箱口令!", 401);
+                        return;
+                    }
+                    if (!String.valueOf(mailCode).toLowerCase().equals(mailbox.toLowerCase())) {
+                        // 记录用户失败日志
+                        LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "邮箱口令错误");
+                        // 删除缓存邮箱口令
+                        LocalCache.remove(CacheConstants.MAIL_CODE_KEY + username);
+                        ResponseInfo.doResponse(response, "邮箱口令错误!", 401);
+                        return;
+                    }
                 }
             }
+            filterChain.doFilter(request, response);
+        } catch (Exception e) {
+            ResponseInfo.doResponse(response, "邮箱口令错误!", 401);
+            return;
         }
-        filterChain.doFilter(request, response);
     }
 }

+ 2 - 4
backend/src/main/java/com/jiayue/ssi/filter/SqlFilter.java

@@ -21,12 +21,10 @@ import java.util.Enumeration;
 * @author xsl
 * @since 2023/05/19
 */
-//@RequiredArgsConstructor
-//@Order(4)
-//@Slf4j
-//@Component
+@RequiredArgsConstructor
 @Order(6)
 @Slf4j
+@Component
 public class SqlFilter  extends OncePerRequestFilter {
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

+ 47 - 51
backend/src/main/java/com/jiayue/ssi/filter/VerifyCodeFilter.java

@@ -9,6 +9,8 @@ import javax.servlet.http.HttpServletResponse;
 
 import com.jiayue.ssi.constant.Constants;
 import com.jiayue.ssi.factory.LoginFactory;
+import com.jiayue.ssi.util.IPUtils;
+import com.jiayue.ssi.util.ResponseInfo;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
@@ -20,11 +22,11 @@ import com.jiayue.ssi.util.LocalCache;
 import lombok.RequiredArgsConstructor;
 
 /**
-* 验证码过滤器
-*
-* @author xsl
-* @since 2023/02/20
-*/
+ * 验证码过滤器
+ *
+ * @author xsl
+ * @since 2023/02/20
+ */
 @RequiredArgsConstructor
 @Order(7)
 public class VerifyCodeFilter extends OncePerRequestFilter {
@@ -32,53 +34,47 @@ public class VerifyCodeFilter extends OncePerRequestFilter {
 
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
-        if ("POST".equalsIgnoreCase(request.getMethod()) && defaultFilterProcessUrl.equals(request.getServletPath())) {
-            // 验证码验证
-            String username = request.getParameter("username");
-            String requestCaptcha = request.getParameter("code");
-            String verifyuuid = request.getParameter("verifyuuid");
-            Object uuidObj = LocalCache.get(CacheConstants.CAPTCHA_CODE_KEY + verifyuuid);
-            // 校验服务端验证码
-            if (uuidObj==null || "".equals(uuidObj)){
-                // 记录验证码失败日志
-                LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
-                response.addHeader("Access-Control-Allow-Origin", "*");
-                response.setContentType("text/html;charset=UTF-8");
-                response.setStatus(401);
-                response.getWriter().write("验证码无效,需要重新获取!");
-                return;
-            }
-            // 校验页面验证码
-            if (StringUtils.isEmpty(requestCaptcha)) {
-                // 记录验证码失败日志
-                LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
-                response.addHeader("Access-Control-Allow-Origin", "*");
-                response.setContentType("text/html;charset=UTF-8");
-                response.setStatus(401);
-                response.getWriter().write("非法访问,验证码错误!");
-                return;
-            }
-            if (requestCaptcha.length()!=4){
-                // 记录验证码失败日志
-                LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
-                response.addHeader("Access-Control-Allow-Origin", "*");
-                response.setContentType("text/html;charset=UTF-8");
-                response.setStatus(401);
-                response.getWriter().write("需要4位验证码!");
-                return;
-            }
-            if (!String.valueOf(uuidObj).toLowerCase().equals(requestCaptcha.toLowerCase())) {
-                // 记录验证码失败日志
-                LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
-                // 删除缓存验证码
-                LocalCache.remove(CacheConstants.CAPTCHA_CODE_KEY + verifyuuid);
-                response.addHeader("Access-Control-Allow-Origin", "*");
-                response.setContentType("text/html;charset=UTF-8");
-                response.setStatus(401);
-                response.getWriter().write("验证码错误!");
-                return;
+        try {
+            if ("POST".equalsIgnoreCase(request.getMethod()) && defaultFilterProcessUrl.equals(request.getServletPath())) {
+                // 验证码验证
+                String username = request.getParameter("username");
+                String requestCaptcha = request.getParameter("code");
+                String verifyuuid = request.getParameter("verifyuuid");
+                String murmur = request.getParameter("murmur");
+                Object uuidObj = LocalCache.get(CacheConstants.CAPTCHA_CODE_KEY + verifyuuid + murmur);
+                // 校验服务端验证码
+                if (uuidObj == null || "".equals(uuidObj)) {
+                    // 记录验证码失败日志
+                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
+                    ResponseInfo.doResponse(response, "验证码无效,需要重新获取!", 401);
+                    return;
+                }
+                // 校验页面验证码
+                if (StringUtils.isEmpty(requestCaptcha)) {
+                    // 记录验证码失败日志
+                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
+                    ResponseInfo.doResponse(response, "非法访问,验证码错误!", 401);
+                    return;
+                }
+                if (requestCaptcha.length() != 4) {
+                    // 记录验证码失败日志
+                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
+                    ResponseInfo.doResponse(response, "需要4位验证码!", 401);
+                    return;
+                }
+                if (!String.valueOf(uuidObj).toLowerCase().equals(requestCaptcha.toLowerCase())) {
+                    // 记录验证码失败日志
+                    LoginFactory.recordLogininfor(username, Constants.LOGIN_FAIL, "验证码错误");
+                    // 删除缓存验证码
+                    LocalCache.remove(CacheConstants.CAPTCHA_CODE_KEY + verifyuuid + murmur);
+                    ResponseInfo.doResponse(response, "验证码错误!", 401);
+                    return;
+                }
             }
+            filterChain.doFilter(request, response);
+        } catch (Exception e) {
+            ResponseInfo.doResponse(response, "验证码校验失败!", 401);
+            return;
         }
-        filterChain.doFilter(request, response);
     }
 }

+ 4 - 0
backend/src/main/java/com/jiayue/ssi/filter/VerifySmFilter.java

@@ -10,9 +10,11 @@ import com.jiayue.ssi.util.IPUtils;
 import com.jiayue.ssi.util.JwtTokenUtil;
 import com.jiayue.ssi.util.ResponseInfo;
 import com.jiayue.ssi.util.SM2CryptUtils;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
 import org.springframework.web.filter.OncePerRequestFilter;
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -29,8 +31,10 @@ import java.util.Map;
  * @author xsl
  * @since 2023/02/27
  */
+@RequiredArgsConstructor
 @Order(3)
 @Slf4j
+@Component
 public class VerifySmFilter extends OncePerRequestFilter {
     private String defaultFilterProcessUrl = "/user/login";
 

+ 2 - 7
backend/src/main/java/com/jiayue/ssi/filter/XssEscapeFilter.java

@@ -5,27 +5,22 @@ package com.jiayue.ssi.filter;
  */
 
 import com.jiayue.ssi.servlet.XssEscapeHttpServletRequestWrapper;
-import com.jiayue.ssi.util.IPUtils;
 import com.jiayue.ssi.util.ResponseInfo;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 import org.springframework.web.filter.OncePerRequestFilter;
-
 import javax.servlet.*;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 //拦截请求
-//@RequiredArgsConstructor
-//@Order(3)
-//@Slf4j
-//@Component
+@RequiredArgsConstructor
 @Order(5)
 @Slf4j
+@Component
 public class XssEscapeFilter extends OncePerRequestFilter {
-
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
         try {

+ 2 - 25
backend/src/main/java/com/jiayue/ssi/filter/XssKeywordsFilter.java

@@ -21,47 +21,26 @@ import java.io.IOException;
  * @author xsl
  * @since 2023/05/16
  */
-//@RequiredArgsConstructor
-//@Order(2)
-//@Slf4j
-//@Component
-
+@RequiredArgsConstructor
 @Order(4)
 @Slf4j
+@Component
 public class XssKeywordsFilter extends OncePerRequestFilter {
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) {
         try {
             XssKeywordsHttpServletRequestWrapper xssRequest = new XssKeywordsHttpServletRequestWrapper(request);
-//            String method = request.getMethod();
-//
-//            String param = "";
-
-//            if ("POST".equalsIgnoreCase(method)) {
-//                param = this.getBodyString(xssRequest.getReader());
-//                if (StringUtils.isNotBlank(param)) {
-//                    if (xssRequest.checkXSSAndSql(param)) {
-//                        ResponseInfo.doResponse(response, "您所访问的页面请求中有违反安全规则元素存在,拒绝访问!", 410);
-//                        return;
-//                    }
-//                }
-//            }
-
             if (xssRequest.checkParameter()) {
                 ResponseInfo.doResponse(response, "您所访问的页面请求中有违反安全规则元素存在,拒绝访问!", 410);
                 return;
             }
-
             filterChain.doFilter(xssRequest, response);
         } catch (Exception e) {
-//            log.error(IPUtils.getIpAddr(request) + "访问系统失败", e);
             ResponseInfo.doResponse(response, "访问失败,联系管理员!", 401);
             return;
         }
-
     }
 
-
     // 获取request请求body中参数
     public String getBodyString(BufferedReader br) {
         String inputLine;
@@ -75,10 +54,8 @@ public class XssKeywordsFilter extends OncePerRequestFilter {
             e.printStackTrace();
         }
         return str;
-
     }
 
-
     @Override
     public void destroy() {
 

+ 1 - 0
ui/package.json

@@ -23,6 +23,7 @@
     "echarts": "5.4.0",
     "element-ui": "2.15.12",
     "file-saver": "2.0.5",
+    "fingerprintjs2": "^2.1.4",
     "font-awesome": "^4.7.0",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",

+ 54 - 23
ui/src/views/login/index.vue

@@ -99,9 +99,10 @@ export default {
         // 邮箱验证码
         mailbox: ''
       },
+      murmur: '',
       verifyuuid: '',
       // 是否使用邮箱口令
-      useSendMail:false,
+      useSendMail: false,
       // 是否已经发送了验证码
       isMailSend: false,
       // 计时器对象
@@ -110,7 +111,7 @@ export default {
       counter: 60,
       // 文本
       sendBtnText: '点击发送邮箱',
-      captchaUrl: '/getVerifyCode',
+      captchaUrl: this.getCaptcha,
       captchaText: '',
       loginRules: {
         /*  username: [{ required: true, trigger: 'blur', validator: validateUsername }],
@@ -142,23 +143,48 @@ export default {
       immediate: true
     }
   },
-  created(){
+  created() {
     // 获取是否邮箱口令
-    this.$axios.get('/sysParameterController/getUseSendMail').then((res) => {
-      this.useSendMail = JSON.parse(res.data)
-    }).catch((error) => {
-      // 登录失败刷新验证码
-      this.updateCaptcha()
-      this.loginForm.verifyCode = ''
-      this.loginForm.mailbox = ''
-      this.reset()
-      this.loading = false
-    })
+    // this.$axios.get('/sysParameterController/getUseSendMail').then((res) => {
+    //   this.useSendMail = JSON.parse(res.data)
+    // }).catch((error) => {
+    //   // 登录失败刷新验证码
+    //   this.updateCaptcha()
+    //   this.loginForm.verifyCode = ''
+    //   this.loginForm.mailbox = ''
+    //   this.reset()
+    //   this.loading = false
+    // })
+    (async () => {
+      const f = await this.getFinger()
+      // 指纹
+      this.murmur = f
+      // 加载验证码
+      this.getCaptcha()
+    })();
   },
   mounted() {
-    this.getCaptcha()
+
   },
   methods: {
+    getFinger() {
+      const Fingerprint2 = require('fingerprintjs2')
+      return new Promise(resolve => {
+        if (window.requestIdleCallback) {
+          requestIdleCallback(function () {
+            Fingerprint2.getV18(function (result) {
+              resolve(result)
+            })
+          })
+        } else {
+          setTimeout(function () {
+            Fingerprint2.getV18(function (result) {
+              resolve(result)
+            })
+          }, 500)
+        }
+      })
+    },
     // 当账号变化时,重置发送按钮
     onUsernameChange() {
       this.reset()
@@ -198,7 +224,7 @@ export default {
     /**
      * 发送邮箱验证码
      */
-    sendMailCode:debounce(function(){
+    sendMailCode: debounce(function () {
       // 判断账户是否已经输入
       if (!this.loginForm.username) {
         this.$message.error('请输入账号')
@@ -217,20 +243,24 @@ export default {
       ).then((res) => {
         this.$message.success('邮件发送成功')
       })
-    },1000),
+    }, 1000),
     // 获取验证码
-    getCaptcha:debounce(function(){
-      this.$axios.get('/getVerifyCode').then((res) => {
+    getCaptcha: debounce(function () {
+      var searchParams = {
+        murmur: this.murmur
+      }
+      this.$axios.get('/getVerifyCode',
+        {params: searchParams}).then((res) => {
         this.verifyuuid = res.data.uuid
         this.captchaUrl = 'data:image/gif;base64,' + res.data.imgBase64;
         this.captchaText = res.data.captchaText
       })
-    },1000),
+    }, 1000),
     updateCaptcha() {
       // 更新验证码
       this.getCaptcha()
     },
-    handleLogin:debounce(function(){
+    handleLogin: debounce(function () {
       this.$refs.loginForm.validate(valid => {
         if (valid) {
           this.loading = true
@@ -252,12 +282,13 @@ export default {
             password: this.loginForm.password,
             code: this.loginForm.verifyCode,
             verifyuuid: this.verifyuuid,
-            mailbox: this.loginForm.mailbox
+            mailbox: this.loginForm.mailbox,
+            murmur: this.murmur
           }
           this.$axios.post('/user/login', param).then((res) => {
             let tokenStr = doEncrypt(res.data)
             let sign = doSign(res.data)
-            sessionStorage.setItem('jy', tokenStr+'&'+sign)
+            sessionStorage.setItem('jy', tokenStr + '&' + sign)
             // 清空路由菜单
             store.commit('SET_R', [])
             this.$router.push('/dashboard')
@@ -275,7 +306,7 @@ export default {
           return false
         }
       })
-    },1000)
+    }, 1000)
   }
 }
 </script>

+ 5 - 0
ui/yarn.lock

@@ -4389,6 +4389,11 @@
     "locate-path" "^5.0.0"
     "path-exists" "^4.0.0"
 
+"fingerprintjs2@^2.1.4":
+  "integrity" "sha512-veP2yVsnYvjDVkzZMyIEwpqCAQfsBLH+U4PK5MlFAnLjZrttbdRqEArE1fPcnJFz5oS5CrdONbsV7J6FGpIJEQ=="
+  "resolved" "https://registry.npmmirror.com/fingerprintjs2/-/fingerprintjs2-2.1.4.tgz"
+  "version" "2.1.4"
+
 "flat-cache@^3.0.4":
   "integrity" "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg=="
   "resolved" "https://registry.npmmirror.com/flat-cache/-/flat-cache-3.0.4.tgz"