uni-app 接入極驗(yàn)驗(yàn)證碼攻略

背景

uni-app 的項(xiàng)目中需要接入極驗(yàn)驗(yàn)證碼,根據(jù)極驗(yàn)官方文檔,只能在微信的 wxml 頁(yè)面中引入模板,但是對(duì)于每個(gè)頁(yè)面都有接口調(diào)用的情況下,手動(dòng)加是不可能的,開發(fā)量大,測(cè)試工作量也大,需要回歸整個(gè)app,但是官方也沒有提供類似全局api的形式給到 js 去調(diào)用,小程序不像H5 是可以臨時(shí)插入dom進(jìn)行操作的,所有要做到全局把控,只能通過中間頁(yè)的形式。

實(shí)現(xiàn)思路

思路:通過小程序里面建一個(gè)中間頁(yè)面,在接口響應(yīng)的時(shí)候,根據(jù) code 碼跳轉(zhuǎn)到承載極驗(yàn)驗(yàn)證碼的頁(yè)面,在這個(gè)頁(yè)面里面做相關(guān)的邏輯處理,成功之后在返回到上一個(gè)頁(yè)面即可。為了不占用主包的大小,所以這個(gè)中間頁(yè)最好放在分包里面。為了保存數(shù)據(jù),在頁(yè)面中使用,可以將數(shù)據(jù)存在 vuex 中,這樣可以全局讀取,進(jìn)行二次驗(yàn)證傳遞給接口。

實(shí)現(xiàn)步驟

申請(qǐng)插件

登陸微信小程序的后臺(tái),在設(shè)置-第三方服務(wù)-插件管理中添加插件,通過 appid(wxefa63d84fe9f64a2)查找并添加驗(yàn)證碼插件,等待極驗(yàn)通過申請(qǐng)即可使用。

插件通過后,可以在微信開發(fā)者工具詳情-插件信息中查看插件的版本號(hào)


配置插件

  • 在文件src/manifest.json中找到微信相關(guān)的配置,加入插件:
"mp-weixin": { /* 微信小程序特有相關(guān) */
    "appid": "xx",
    "setting": {
      "urlCheck": false
    },
    "usingComponents": true,
    "optimization": {
      "subPackages": true
    },
    "plugins": {
      "myPlugin": {
        "version": "1.3.3",
        "provider": "wxefa63d84fe9f64a2"
      }
    }
  },
  • src/pages.json中找到分包subPackages,加入承載驗(yàn)證碼操作的中間頁(yè),在這個(gè)頁(yè)面引入插件,就可以在當(dāng)前頁(yè)面中使用:
"subPackages": [
  "root": "packageSecond",
  "pages": [
    {
      "path": "pages/geetest/geetest",
      "style": {
        "navigationBarTitleText": "驗(yàn)證碼",
        "mp-weixin": {
           "usingComponents": {
              "captcha": "plugin://myPlugin/captcha"
            }
         }
       }
    }
  ]
]

中間頁(yè)

新建中間頁(yè),在分包目錄下,如src/packageSecond/pages下新建一個(gè)中間頁(yè)面geetest/geetest.vue,頁(yè)面中引入極驗(yàn)驗(yàn)證碼的模板,按照vue的語(yǔ)法轉(zhuǎn)換模板,監(jiān)聽成功和失敗的時(shí)間,做相應(yīng)的業(yè)務(wù)邏輯處理,根據(jù)官方文檔,微信小程序的模板寫法<captcha id="captcha" wx:if="{{loadCaptcha}}" gt="{{gt}}" challenge="{{challenge}}" offline="{{offline}}" bindonSuccess="captchaSuccess" />
wx:if換成v-if,{{}}語(yǔ)法換成 vue 模板語(yǔ)法,事件綁定換成@onSuccess

// geetest/geetest.vue
<template>
  <view class="container">
    <view class="gettest-box">
      <captcha
        v-if="geetestObj.loadCaptcha"
        :gt="geetestObj.gt"
        :challenge="geetestObj.challenge"
        :offline="geetestObj.offline"
        @onError="error"
        @onSuccess="success"
      />
    </view>
  </view>
</template>
<script>
import { mapState } from 'vuex'
import store from 'store'

export default {
  computed: {
    ...mapState({
      geetestObj: state => state.geetestObj,
    }),
  },
  methods: {
    error(e) {
      console.log('我是擠眼驗(yàn)證碼,我出錯(cuò)了')
    },
    async success(result) {
      try {
        store.commit('SET_GEETEST_RESULT', result.detail)
        const secondVerifyUrl = '/api/secondVerify'
        const reportResultUrl = '/api/reportResult'
        const options = {stone: true, json: true}
        const resultData = result.detail
  
        // 二次驗(yàn)證需要的參數(shù)
        const secondVerifParams = {
          challenge: resultData.geetest_challenge,
          serverStatus: this.geetestObj.serverStatus,
          validate: resultData.geetest_validate,
          seccode: resultData.geetest_seccode,
          devicePlatform: 'h5',
        }

        const secondVerify = await postRequest(secondVerifyUrl, secondVerifParams, options)
        let { resultCode = '' } = secondVerify
        if (resultCode) {
          const params = {
            challenge: resultData.geetest_challenge,
            serverStatus: this.geetestObj.serverStatus,
            result: resultCode === '200' ? 1 : 0,
            devicePlatform: 'h5',
          }
          const reportResult = await postRequest(reportResultUrl, params, options)
          if (reportResult.resultCode) {
            const pages = getCurrentPages() // 當(dāng)前頁(yè)面
            const beforePage = pages[pages.length - 2] // 上一頁(yè)
            const options = beforePage.options
            uni.navigateBack({
              success: function() {
                beforePage.onLoad(options) // 執(zhí)行上一頁(yè)的onLoad方法
              }
            })
          }
        }
      } catch(e) {
        console.log(e)
      }
    }
  }
}
</script>
<style lang="scss">
.container {
  width: 100vw;
  height: 100vh;
  position: relative;

  .gettest-box {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>

監(jiān)聽接口

封裝好的接口請(qǐng)求中監(jiān)聽響應(yīng)的狀態(tài),將數(shù)據(jù)存到 store 中,在驗(yàn)證碼中間頁(yè)拿到數(shù)據(jù),進(jìn)行二次驗(yàn)證的時(shí)候傳給后端接口。

// server.js
fetchInstance.interceptors.response.use(res => {
    // #ifdef MP-WEIXIN
    if (res.data.status === 485) {
        const data = res.data.data
        const obj = {
            loadCaptcha: data.newCaptcha,
            gt: data.gt,
            challenge: data.challenge,
            offline: !data.serverStatus,
            serverStatus: data.serverStatus
        }
        store.commit('SET_GEETEST_OBJ', obj)
        uni.navigateTo({
            url: '/packageSecond/pages/geetest/geetest'
        })
    }
    // #endif
})

以上就是接入的這個(gè)過程。
效果如下:



參考:
https://docs.geetest.com/sensebot/apirefer/api/miniprogram
https://docs.geetest.com/sensebot/deploy/client/miniprogram
https://uniapp.dcloud.io/component/mp-weixin-plugin

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容