vue + typescript + 极验登录验证的实现方法


Posted in Javascript onJune 27, 2019

此功能基于vue(v2.6.8) + typescript(v3.3.3333), 引入极验(geetest v3+)(官方api),使用其product: 'bind'模式, 页面挂载后初始化ininGeetest,点击登录按钮后先做表单验证,通过后弹出滑块框,拖动验证成功,执行登录方法。

本项目为前后端分离,所以后端部署部分,请自行参考文档操作

vue + typescript + 极验登录验证的实现方法

后台接口:

vue + typescript + 极验登录验证的实现方法

vue + typescript + 极验登录验证的实现方法

vue + typescript + 极验登录验证的实现方法

开始:/public/js目录添加 jquery-1.12.3.min.js文件 和 gt.js(下载)在/public/index.html中引入以上添加的两个文件login.vue使用注意事项:要注意在gt.js中,initGeetest已被挂载到window对象

vue + typescript + 极验登录验证的实现方法

页面可能报错: Uncaught SyntaxError: Unexpected token <

vue + typescript + 极验登录验证的实现方法

vue + typescript + 极验登录验证的实现方法

将报错对象添加到与public同级的static目录下(没有则新建),修改引入路径即可。

源码:

<script lang="ts">
import { isValidUsername } from '@/utils/validate';
import { Component, Vue, Watch } from 'vue-property-decorator';
import { Route } from 'vue-router';
import { ElForm } from 'element-ui/types/form';
import { Loading } from 'element-ui';

import { Action } from 'vuex-class';
import AuthServices from '@/services/user/auth.ts';
import ThirdpartyServices from '@/services/thirdparty/index.ts';

const validateUsername = (rule: any, value: string, callback: any) => {
 if (! value) {
  callback(new Error('用户名不能为空'));
 // } else if (!isValidUsername(value)) {
 //  callback(new Error('请输入正确的用户名'));
 } else {
  callback();
 }
};
const validatePass = (rule: any, value: string, callback: any) => {
  if (! value) {
  callback(new Error('密码不能为空'));
 // } else if (value.length < 5) {
 //  callback(new Error('密码不能小于5位'));
 } else {
  callback();
 }
};

@Component({
 name: 'login',
})
export default class Login extends Vue {
 @Action('auth/login') private login_action!: CCS.LoginAction;

 private loginForm = { username: '', password: '' };
 private loginRules = {
  username: [{trigger: 'blur', validator: validateUsername }],
  password: [{trigger: 'blur', validator: validatePass }],
 };
 private loading = false;
 private redirect: string | undefined = undefined;
 private captchaEntity: any;
 // private loadingInstance: any;

 @Watch('$route', { immediate: true }) private OnRouteChange(route: Route) {
  this.redirect = route.query && route.query.redirect as string;
 }

 // private created() {
 //  this.loadingInstance = Loading.service({
 //   customClass: 'login_loading',
 //   text: '正在初始化,请稍后',
 //   fullscreen: true,
 //   lock: true,
 //  });
 // }

 /** ==================== 验证 START ========================= */
 /**
  * 页面挂载后,后台获取初始化initGeetest所需参数值
  */
 private async mounted() {
  ThirdpartyServices.geetest_init().then((result) => {
   // this.loadingInstance.close();
   if (result.status) {
    this.initGeetest(result.data);
   } else {
    this.$message({ type: 'error', message: result.message });
   }
  });
 }
  /**
  * initGeetest 初始化
  */
 private initGeetest(param: CCS.GeettestInitType) {
  if ( ! (window as any) || ! (window as any).initGeetest ) {
   return false;
  }
  (window as any).initGeetest({
   gt: param.gt,
   challenge: param.challenge,
   offline: ! param.success,
   new_captcha: param.newcaptcha,
   timeout: '5000',
   product: 'bind',
   width: '300px',
   https: true,

  }, this.captchaObj_callback);
 }
 /**
  * 初始化后的回调函数
  */
 private async captchaObj_callback(captchaObj: any) {
  this.captchaEntity = captchaObj; // promise对象
  captchaObj
   .onReady(() => { // 验证码就位
   })
   .onSuccess(() => {
    const rst = captchaObj.getValidate();
    if (!rst) {
     this.$message({ type: 'warning', message: '请完成验证'});
    }

    // 调用后台check this.captchaObj
    this.verify_check(rst);
   })
   .onError((err: Error) => {
    console.log(err);
   });
 }
 /**
  * 后台验证初始化结果
  */
 private async verify_check(validateResult: any) {
  ThirdpartyServices.geetest_checked(validateResult.geetest_challenge, validateResult.geetest_validate, validateResult.geetest_seccode ).then((result) => {
   if (result.status && result.data.result) {
    // 验证通过,发送登录请求
    this.handleLogin(result.data.token);
   } else {
    this.$message({ type: 'error', message: '验证失败'});
    return false;
   }
  });
 }
 /** ==================== 验证 END ========================= */
 /**
  * 点击登录按钮,弹出验证框
  */
 private login_btn_click() {
  (this.$refs.refform as ElForm).validate((valid) => {
   if (valid) {
    this.captchaEntity.verify(); // 显示验证码
   }
  });
 }
 /**
  * 验证成功,发送登录请求
  */
 private async handleLogin(token: string) {
  this.loading = true;
  const { status, message} = await this.login_action({username: this.loginForm.username.trim(), password: this.loginForm.password, token});

  this.loading = false;
  if (status) {
   this.$message({type: 'success', message: '登录成功'});
   this.$router.push({ path: this.redirect || '/' });
  } else {
   this.$message({type: 'error', message});
  }
 }
}
</script>

<template>
 <div class="login-container">
  <div class="login_form_wraper">
   <div class="logo_show">
    <img :src="require('@/assets/images/logo_w328.png')">
   </div>
   <img class="form_bg" :src="require('@/assets/images/login_form.png')">
   <el-form ref="refform" class="login-form" auto-complete="on" label-position="left"
     :model="loginForm" :rules="loginRules">
    <el-form-item prop="username">
     <el-input v-model="loginForm.username" name="username" type="text" auto-complete="on" placeholder="用户名"/>
     <i class="iconfont icon-zhanghaodenglu icon_prefix"></i>
    </el-form-item>
    <el-form-item prop="password">
     <el-input v-model="loginForm.password" name="password" type="password" auto-complete="on" placeholder="密码"
      @keyup.enter.native="handleLogin" />
     <i class="iconfont icon-mima icon_prefix"></i>
    </el-form-item>

    <el-form-item class="login_btn">
     <el-button v-if="!loading" @click.native.prevent="login_btn_click">登录</el-button>
     <el-button :loading="loading" v-else @click.native.prevent="handleLogin">登录中</el-button>
    </el-form-item>
   </el-form>

  </div>
 </div>
</template>

<style lang="stylus" scoped>
@import '~@/assets/styles/var.styl';
@import '~@/assets/styles/pages/login.styl';

.login-container
 pass

</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
url 特殊字符 传递参数解决方法
Jan 01 Javascript
避免回车键导致的页面无意义刷新的解决方法
Apr 12 Javascript
Moment.js 不容错过的超棒Javascript日期处理类库
Apr 15 Javascript
js判断两个日期是否相等的方法
Sep 10 Javascript
Javascript倒计时页面跳转实例小结
Sep 11 Javascript
js使用eval解析json(js中使用json)
Jan 17 Javascript
javascript与有限状态机详解
May 08 Javascript
Javascript中的getUTCHours()方法使用详解
Jun 10 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
May 26 Javascript
JavaScript实现前端分页控件
Apr 19 Javascript
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
Mar 28 jQuery
jQuery表单选择器用法详解
Aug 22 jQuery
JS前端知识点 运算符优先级,URL编码与解码,String,Math,arguments操作整理总结
Jun 27 #Javascript
JS前端知识点offset,scroll,client,冒泡,事件对象的应用整理总结
Jun 27 #Javascript
ES6 let和const定义变量与常量的应用实例分析
Jun 27 #Javascript
vue响应式更新机制及不使用框架实现简单的数据双向绑定问题
Jun 27 #Javascript
微信小程序实现form表单本地储存数据
Jun 27 #Javascript
ES6 class的应用实例分析
Jun 27 #Javascript
ES6 Promise对象的应用实例分析
Jun 27 #Javascript
You might like
PHP开发中的错误收集,不定期更新。
2011/02/03 PHP
ThinkPHP整合百度Ueditor图文教程
2014/10/21 PHP
Thinkphp实现站点静态化的方法详解
2017/03/21 PHP
解决Laravel5.x的php artisan migrate数据库迁移创建操作报错SQLSTATE[42000]
2020/04/06 PHP
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
2012/01/15 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
关闭ie窗口清除Session的解决方法
2014/01/10 Javascript
JavaScript window.location对象
2014/11/14 Javascript
分享33个jQuery与CSS3实现的绚丽鼠标悬停效果
2014/12/15 Javascript
jQuery增加自定义函数的方法
2015/07/18 Javascript
javascript实现超炫的向上滑行菜单实例
2015/08/03 Javascript
js获取隐藏元素宽高的实现方法
2016/05/19 Javascript
Javascript OOP之面向对象
2016/07/31 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
关于vue-router路径计算问题
2017/05/10 Javascript
使用AngularJS编写多选按钮选中时触发指定方法的指令代码详解
2017/07/24 Javascript
vue跨域解决方法
2017/10/15 Javascript
使用nvm管理不同版本的node与npm的方法
2017/10/31 Javascript
Node.js引入UIBootstrap的方法示例
2018/05/11 Javascript
JS实现随机生成10个手机号的方法示例
2018/12/07 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
JS面向对象编程实现的拖拽功能案例详解
2020/03/03 Javascript
python如何为创建大量实例节省内存
2018/03/20 Python
Python爬虫包BeautifulSoup实例(三)
2018/06/17 Python
Python3 pickle对象串行化代码实例解析
2020/03/23 Python
pycharm解决关闭flask后依旧可以访问服务的问题
2020/04/03 Python
浅谈Python中的生成器和迭代器
2020/06/19 Python
杭州-DOTNET笔试题集
2013/09/25 面试题
JDBC操作数据库的基本流程是什么
2014/10/28 面试题
会计系中文个人求职信
2013/12/24 职场文书
24岁生日感言
2014/01/13 职场文书
珍珠鸟教学反思
2014/02/01 职场文书
三八红旗手先进事迹材料
2014/05/13 职场文书
捐书倡议书
2014/08/29 职场文书
2015年乡镇民政工作总结
2015/05/13 职场文书
工作态度怎么写
2015/06/25 职场文书