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 相关文章推荐
jQuery 在光标定位的地方插入文字的插件
May 10 Javascript
js二维数组排序的简单示例代码
Jan 24 Javascript
javascript删除一个html元素节点的方法
Dec 20 Javascript
用js写的一个路由(简单实例)
Sep 24 Javascript
jQuery实现表格元素动态创建功能
Jan 09 Javascript
Vue Cli与BootStrap结合实现表格分页功能
Aug 18 Javascript
Angularjs使用过滤器完成排序功能
Sep 20 Javascript
Vue-cli-webpack搭建斗鱼直播步骤详解
Nov 17 Javascript
js+html5实现手机九宫格密码解锁功能
Jul 30 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
Jan 02 Javascript
基于Fixed定位的框选功能的实现代码
May 13 Javascript
Vue SPA 首屏优化方案
Feb 26 Vue.js
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
《雄兵连》系列首部大电影《烈阳天道》:可能是因为期望值太高了
2020/08/18 国漫
特详细的PHPMYADMIN简明安装教程
2008/08/01 PHP
dedecms系统的广告设置代码 基础版本
2010/04/09 PHP
发款php蜘蛛统计插件只要有mysql就可用
2010/10/12 PHP
PHP中PDO的错误处理
2011/09/04 PHP
PHP动态分页函数,PHP开发分页必备啦
2011/11/07 PHP
php实现博客,论坛图片防盗链的方法
2016/10/15 PHP
php使用FFmpeg接口获取视频的播放时长、码率、缩略图以及创建时间
2016/11/07 PHP
tp5框架使用composer实现日志记录功能示例
2019/01/10 PHP
JQuery 无废话系列教程(一) jquery入门 [推荐]
2009/06/23 Javascript
js的逻辑运算符 ||
2010/05/31 Javascript
兼容主流浏览器的iframe自适应高度js脚本
2014/01/10 Javascript
jQuery ajax请求struts action实现异步刷新
2017/04/19 jQuery
JavaScript简介_动力节点Java学院整理
2017/06/26 Javascript
angularjs实现时间轴效果的示例代码
2017/11/29 Javascript
jQuery动态移除与增加onclick属性的方法详解
2018/06/07 jQuery
vue组件内部引入外部js文件的方法
2020/01/18 Javascript
python字典get()方法用法分析
2015/04/17 Python
剖析Django中模版标签的解析与参数传递
2015/07/21 Python
TensorFlow实现非线性支持向量机的实现方法
2018/04/28 Python
Python 类,property属性(简化属性的操作),@property,property()用法示例
2019/10/12 Python
python求一个字符串的所有排列的实现方法
2020/02/04 Python
关于python 的legend图例,参数使用说明
2020/04/17 Python
Python学习之os模块及用法
2020/06/03 Python
Python中操作各种多媒体,视频、音频到图片的代码详解
2020/06/04 Python
15个应该掌握的Jupyter Notebook使用技巧(小结)
2020/09/23 Python
Html5新标签解释及用法
2012/02/17 HTML / CSS
浅析HTML5:'data-'属性的作用
2018/01/23 HTML / CSS
德国传统玻璃制造商:Cristalica
2018/04/23 全球购物
德国前卫设计师时装在线商店:Luxury Loft
2019/11/04 全球购物
英国买鞋网站:Charles Clinkard
2019/11/14 全球购物
加拿大领先的时尚和体育零售商:Sporting Life
2019/12/15 全球购物
不开辟用于交换数据的临时空间,如何完成字符串的逆序
2012/12/02 面试题
什么是托管函数?托管函数有什么用?
2014/06/15 面试题
贴吧吧主申请感言
2015/08/03 职场文书
在HTML5 localStorage中存储对象的示例代码
2021/04/21 Javascript