Browse Source

极验验证登录

Michael Wang 4 năm trước cách đây
mục cha
commit
1a03e123ab

+ 1 - 1
prebuild.js

@@ -1,6 +1,6 @@
 const packageJson = require("./package.json");
 
-if (packageJson.dependencies.iview !== "^3.5.2") {
+if (packageJson.dependencies.iview !== "^3.5.4") {
   console.log("iview 的版本不要轻易升级,一定要充分测试。");
   process.exit(1);
 }

+ 10 - 4
public/index.html

@@ -32,7 +32,12 @@
   <body>
     <div id="app-placeholder">
       <div
-        style="height: 120px; font-size: 40px; text-align: center; width: 100vw"
+        style="
+          height: 120px;
+          font-size: 40px;
+          text-align: center;
+          width: 100vw;
+        "
       >
         程序加载中...
       </div>
@@ -44,8 +49,8 @@
           "https://ecs.qmth.com.cn:8878/oe/login/exam.qmth.com.cn"
         )
       ) {
-        (async function() {
-          !(function(c, b, d, a) {
+        (async function () {
+          !(function (c, b, d, a) {
             c[a] || (c[a] = {});
             c[a].config = {
               pid: "hworw@536497ba86039b9",
@@ -79,7 +84,7 @@
     <!-- baidu tongji -->
     <script>
       var _hmt = _hmt || [];
-      (function() {
+      (function () {
         var hm = document.createElement("script");
         hm.src = "https://hm.baidu.com/hm.js?8f776e9b3eb700921c71576bbba0dac8";
         var s = document.getElementsByTagName("script")[0];
@@ -105,5 +110,6 @@
         //   });
       })();
     </script>
+    <script src="https://static.geetest.com/static/tools/gt.js"></script>
   </body>
 </html>

+ 97 - 0
src/features/Login/GeeTest.vue

@@ -0,0 +1,97 @@
+<template>
+  <div>
+    <!-- <label>完成验证:</label> -->
+    <div id="captcha">
+      <p v-if="loading" class="show">正在加载验证码......</p>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "GeeTest",
+  data() {
+    return { loading: true };
+  },
+  async mounted() {
+    const that = this;
+    // const emit = this.$emit.bind(this);
+    function handler(captchaObj) {
+      that.$emit("on-load", captchaObj);
+      // emit("on-result", captchaObj.getValidate());
+      // $("#submit").click(function (e) {
+      //   var result = captchaObj.getValidate();
+      //   if (!result) {
+      //     // $("#notice").show();
+      //     // setTimeout(function () {
+      //     //   $("#notice").hide();
+      //     // }, 2000);
+      //     e.preventDefault();
+      //   }
+      //   // const dom = $(".geetest_form").clone(true, true);
+      //   // $("#submit").append(dom);
+      //   // $(".geetest_form").children()[0].name = "challenge";
+      //   // $(".geetest_form").children()[1].name = "validate";
+      //   // $(".geetest_form").children()[2].name = "seccode";
+      //   $.ajax({
+      //     url: "/geetest/validate", // 加随机数防止缓存
+      //     type: "POST",
+      //     contentType: "application/json;charset=UTF-8",
+      //     data: JSON.stringify({
+      //       user_id: localStorage.getItem("uuidForEcs"),
+      //       client_type: "Web",
+      //       challenge: document.querySelector(".geetest_form").children()[0]
+      //         .value,
+      //       validate: document.querySelector(".geetest_form").children()[1]
+      //         .value,
+      //       seccode: document.querySelector(".geetest_form").children()[2]
+      //         .value,
+      //     }),
+      //     dataType: "json",
+      //     success: function (data) {
+      //       // 调用 initGeetest 初始化参数
+      //       // 参数1:配置参数
+      //       // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它调用相应的接口
+      //       console.log(data);
+      //       // alert(data);
+      //       // if(data.success) {
+      //       alert(data.msg);
+      //       // }
+      //       // debugger;
+      //     },
+      //   });
+      //   e.preventDefault();
+      // });
+      // 将验证码加到id为captcha的元素里,同时会有三个input的值用于表单提交
+      captchaObj.appendTo("#captcha");
+      captchaObj.onReady(function () {
+        that.loading = false;
+      });
+    }
+
+    const res = await this.$http.post("/api/ecs_core/verifyCode/register", {
+      user_id: localStorage.getItem("uuidForEcs"),
+      client_type: "Web",
+    });
+    // console.log(res);
+    const data = res.data;
+    window.initGeetest(
+      {
+        gt: data.gt,
+        challenge: data.challenge,
+        new_captcha: data.new_captcha, // 用于宕机时表示是新验证码的宕机
+        offline: !data.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注
+        product: "float", // 产品形式,包括:float,popup
+        width: "100%",
+      },
+      handler
+    );
+  },
+};
+</script>
+
+<style>
+.geetest_holder.geetest_wind {
+  min-width: 220px !important;
+}
+</style>

+ 0 - 31
src/features/Login/HiddenRequest.js

@@ -1,31 +0,0 @@
-import { TK_SERVER_HTML_URL } from "@/constants/constants.js";
-
-export default function (uuid) {
-  const url = "/resource.js?u=" + uuid;
-  // TK_SERVER_HTML_URL.replace("http", "http") + ":8000/resource.js?u=" + uuid;
-
-  // if(process.env.NODE_ENV !== 'production')
-  fetch(url);
-  const isElectron = typeof nodeRequire != "undefined";
-  if (!isElectron) return;
-
-  const https = window.nodeRequire("https");
-  // console.log("sent request: ", url);
-  // "https://ecs-test.qmth.com.cn:8878/api/ecs_core" +
-  https
-    .get(url, (response) => {
-      var configContent = "";
-      response
-        .on("data", function (data) {
-          //加载到内存
-          configContent += data;
-        })
-        .on("end", function () {
-          configContent;
-          // console.log("resres", configContent);
-        });
-    })
-    .on("error", () => {
-      https.get(url);
-    });
-}

+ 28 - 4
src/features/Login/Login.vue

@@ -66,7 +66,6 @@
                 v-model="loginForm.accountValue"
                 type="text"
                 size="large"
-                @on-blur="loginForm.accountValue"
               >
                 <i-icon slot="prepend" type="ios-person"></i-icon>
               </i-input>
@@ -77,16 +76,22 @@
                 type="password"
                 size="large"
                 @on-enter="loginForuser"
-                @on-blur="loginForm.accountValue"
               >
                 <i-icon slot="prepend" type="ios-lock"></i-icon>
               </i-input>
             </i-form-item>
 
+            <i-form-item
+              class="form-item-style"
+              style="height: 40px; margin-top: 0px;"
+            >
+              <GeeTest @on-load="handleGtResult" />
+            </i-form-item>
+
             <i-form-item style="position: relative;">
               <div
                 v-if="errorInfo !== ''"
-                style="position: absolute; top: -37px; width: 100%;"
+                style="position: absolute; top: -25px; width: 100%;"
               >
                 <i-alert type="error" show-icon>{{ errorInfo }}</i-alert>
               </div>
@@ -135,6 +140,7 @@ import {
   createEncryptLog,
 } from "@/utils/logger";
 import { isElectron } from "@/utils/util";
+import GeeTest from "./GeeTest";
 
 // 检测devtools.  仅在chrome 72+ 有效。
 let element = new Image();
@@ -164,6 +170,7 @@ export default {
   name: "Login",
   components: {
     DevTools,
+    GeeTest,
   },
   data() {
     return {
@@ -191,6 +198,7 @@ export default {
           },
         ],
       },
+      captchaObj: null,
       loginBtnLoading: false,
       disableLoginBtnBecauseRemoteApp: true,
       disableLoginBtnBecauseVCam: true,
@@ -470,6 +478,10 @@ export default {
       this.loginBtnLoading = true;
       const before = Date.now();
 
+      if (!this.captchaObj.getValidate()) {
+        this.$Message.error("请完成验证");
+        return;
+      }
       try {
         await this.login();
       } finally {
@@ -510,15 +522,22 @@ export default {
         }
 
         let repPara = this.loginForm;
+        const geeForm = document.querySelector(".geetest_form").children;
         // 以下网络请求失败,直接报网络异常错误
         loginResponse = await this.$http.post(
-          "/api/ecs_core/verifyCode/login",
+          "/api/ecs_core/verifyCode/gt/login",
           {
             ...repPara,
             accountType: this.loginType,
             domain: this.schoolDomain,
             rootOrgId: this.QECSConfig.ROOT_ORG_ID,
             alwaysOK: true,
+            // geetest
+            user_id: localStorage.getItem("uuidForEcs"),
+            client_type: "Web",
+            challenge: geeForm[0].value,
+            validate: geeForm[1].value,
+            seccode: geeForm[2].value,
           }
         );
       } else {
@@ -630,6 +649,7 @@ export default {
         window._hmt.push(["_trackEvent", "登录页面", "登录失败", data.desc]);
         createLog({ currentPage: "登录页面", action: "登录失败" });
         this.errorInfo = data.desc;
+        this.captchaObj.reset();
       }
     },
     async checkNewVersion() {
@@ -1026,6 +1046,10 @@ export default {
         this.logout();
       }
     },
+    handleGtResult(captchaObj) {
+      console.log(captchaObj);
+      this.captchaObj = captchaObj;
+    },
   },
 };
 </script>