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 相关文章推荐
根据json字符串生成Html的一种方式
Jan 09 Javascript
js 动态加载事件的几种方法总结
Dec 25 Javascript
百度UEditor编辑器如何关闭抓取远程图片功能
Mar 03 Javascript
JS+CSS实现简单的二级下拉导航菜单效果
Sep 21 Javascript
Node.js Express 框架 POST方法详解
Jan 23 Javascript
jQuery移除或禁用html元素点击事件常用方法小结
Feb 10 Javascript
JavaScript中数组常见操作技巧
Sep 01 Javascript
template.js前端模板引擎使用详解
Oct 10 Javascript
利用Node.js检测端口是否被占用的方法
Dec 07 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
Jun 07 Javascript
JavaScript获取当前url路径过程解析
Dec 27 Javascript
vue使用canvas实现移动端手写签名
Sep 22 Javascript
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
数据库中排序的对比及使用条件详解
2012/02/23 PHP
解析PHP多种序列化与反序列化的方法
2013/06/06 PHP
讲解WordPress中用于获取评论模板和搜索表单的PHP函数
2015/12/28 PHP
laravel 根据不同组织加载不同视图的实现
2019/10/14 PHP
JavaScript实现从数组中选出和等于固定值的n个数
2014/09/03 Javascript
js弹出对话框方式小结
2015/11/17 Javascript
JavaScript模仿Pinterest实现图片预加载功能
2016/10/25 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
2016/12/08 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
vue实现添加标签demo示例代码
2017/01/21 Javascript
关于vue.js过渡css类名的理解(推荐)
2017/04/10 Javascript
Angular2学习教程之ng中变更检测问题详解
2017/05/28 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
2018/09/26 Javascript
vue+element获取el-table某行的下标,根据下标操作数组对象方式
2020/08/07 Javascript
Python返回真假值(True or False)小技巧
2015/04/10 Python
Python基于回溯法子集树模板解决选排问题示例
2017/09/07 Python
Python图像滤波处理操作示例【基于ImageFilter类】
2019/01/03 Python
python实现感知器算法(批处理)
2019/01/18 Python
python初学者,用python实现基本的学生管理系统(python3)代码实例
2019/04/10 Python
Python 使用指定的网卡发送HTTP请求的实例
2019/08/21 Python
Python实现语音识别和语音合成功能
2019/09/20 Python
python网络编程socket实现服务端、客户端操作详解
2020/03/24 Python
Django使用Profile扩展User模块方式
2020/05/14 Python
Django DRF认证组件流程实现原理详解
2020/08/17 Python
CSS3 滤镜 webkit-filter详细介绍及使用方法
2012/12/27 HTML / CSS
CSS3实现曲线阴影和翘边阴影
2016/05/03 HTML / CSS
Auchan Direct波兰:欧尚在线杂货店
2016/10/19 全球购物
Myholidays美国:在线旅游网站
2019/08/16 全球购物
澳大利亚100%丝绸多彩度假装商店:TheSwankStore
2019/09/04 全球购物
一份报关员的职业规划范文
2014/01/08 职场文书
求职意向书
2014/04/01 职场文书
一年级语文下册复习计划
2015/01/17 职场文书
初中政治教学工作总结
2015/08/13 职场文书
资深HR教你写好简历中的自我评价
2019/05/07 职场文书
mysql的Buffer Pool存储及原理
2022/04/02 MySQL
Python简易开发之制作计算器
2022/04/28 Python