在vue3中使用reCAPTCHA(机器人验证服务)

1,701 阅读1分钟

本篇并不过多介绍reCAPTCHA,主要是为了介绍如何接入vue3项目,不包含服务端验证,更多功能请读者自行深入了解。

reCAPTCHA.jpg reCAPTCHA事例.jpg

什么是 reCAPTCHA

reCAPTCHA 是 Google 提供的一项免费服务,可保护您的网站免受垃圾内容和滥用行为的侵扰。它使用高级风险分析技术来区分真人与机器人。开发者指南请参阅官网

用法

使用方式有很多,这里所展示的方式之一为 reCAPTCHA v2 中的编程方式。

在index.html文件中

<script src="https://www.google.com/recaptcha/enterprise.js?render=explicit" async defer></script>

在vue文件中

<template>
  <button @click="verificationRobot">点我,我不是机器人</button>
  <!-- 全屏弹窗 -->
  <div v-if="verificationRobotVisible" class="overlay" @click.stop>
    <div id="verification-robot-html"></div>
  </div>
</template>

<style scoped>
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

<script setup>
import { ref, nextTick } from 'vue'

const verificationRobotVisible = ref(false);
const challenge_response = ref(""); // 令牌

const verificationRobot = async () => {
  if (challenge_response.value) return;
  try {
    verificationRobotVisible.value = true;
    await nextTick();
    // render方法 将容器呈现为reCAPTCHA微件,并返回新创建的微件的ID
    const optWidgetId = window.grecaptcha?.enterprise?.render(
      "verification-robot-html",
      {
        // 您申请的网站密钥
        sitekey: '',
        // 当用户提交成功的响应时执行的回调,并返回令牌
        callback: (response) => {
          challenge_response.value = response;
          verificationRobotVisible.value = false;
        },
        // 遇到错误,并且在恢复连接之前无法继续时执行的回调
        "error-callback": () => {
          verificationRobotVisible.value = false;
          console.log("机器人验证失败,请稍后再试!");
        },
        // 响应过期且用户需要重新验证时执行的回调(就是拿到的令牌过期了)
        "expired-callback": () => {
          challenge_response.value = "";
          verificationRobotVisible.value = true;
          // reset方法 重置reCAPTCHA微件
          nextTick(() => window.grecaptcha?.enterprise?.reset(optWidgetId)); 
        }
      }
    );
  } catch (error) {
    verificationRobotVisible.value = false;
    console.log("机器人验证失败,请稍后再试!");
  }
};
</script>

注意事项

如果页面使用了 keepAlive 要注意,dom被缓存下来会导致下次进来 render 失败,离开页面要销毁掉 verification-robot-html dom元素,所以要使用 v-if

onActivated(() => verificationRobotVisible.value = false);