# 人机校验

在接口安全控制方面，人机校验可以起到关键的防护作用，尤其是在复杂网络环境下，确保系统的安全性和数据的完整性。以下方式提供如何在MultiMarket系统中接入人机校验：

## 接入方式

> 该功能是对接谷歌官方的reCAPTCHA，<https://developers.google.com/recaptcha>

## 涉及接口

login/customer.app.CustomerWebApiService.login global/message.app.VerificationApiService.verifyCodeSend register/customer.app.CustomerWebApiService.register

```
headrs: {
   // 请求头添加 google captcha
   captcha: zxksjkdjskdjsd
}
```

## 接入步骤

> 详细对接文档可见：<https://developers.google.com/recaptcha/docs/display>

### 注册谷歌 reCAPTCHA&#x20;

* 在管理平台注册新网站 <http://www.google.com/recaptcha/admin> , 填写表单并选择适合你的网站的reCAPTCHA版本（v2或v3）
* 完成注册后，你将获得一个“站点密钥”（Site Key）和一个“秘密密钥”（Secret Key）。 站点密钥用于前端，秘密密钥用于后端验证。<mark style="color:red;">**需要提供给MultiMarket进行后端配置。**</mark>

### 前端集成(JS/V3) 示例

1.将以下代码添加到您的 HTML 页面中，通常放在 标签内

```
<script src="https://www.google.com/recaptcha/api.js?render=your_site_key"></script>
```

将 your\_site\_key 替换为您在管理控制台中获取的站点密钥。

2.根据需求在当用户提交表单（登录、注册、获取验证码等）时执行调用 grecaptcha.execute 方法获取接口请求所需参数 `captcha`

```
   <script>
      function onClick(e) {
        e.preventDefault();
        grecaptcha.ready(function() {
          grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'}).then(function(token) {
              // Add your logic to submit to your backend server here.
          });
        });
      }
  </script>
```

3. 在接口请求时放入请求头，传给后端进行效验

```
headrs: {
   // 请求头添加 google captcha
   captcha: zxksjkdjskdjsd
}
```

4. 发起接口请求 通过校验：正常返回请求内容 未通过：`{"msg":"请求参数不合法","code":"F999999","bizCode":"G"}`

### 前端集成(Vue/V3) 示例

1. 下载引入 vue-recaptcha-v3

```
npm i vue-recaptcha-v3 --save
// main.js
import { VueReCaptcha } from 'vue-recaptcha-v3'
app.use(VueReCaptcha, {
    // 替换为您在管理控制台中获取的站点密钥
    siteKey: '6LcNvBUqAAAAABz2_ieWJEtdmyK_-oUUEk04Y1z4',
    loaderOptions: {
        // 由于某些国家的限制，可以选择开启使用 recaptcha.net 而不是 google.com。
        useRecaptchaNet: true
    }
}) 
```

2. 创建 useRecaptcha.js 文件

````
import { useReCaptcha } from 'vue-recaptcha-v3'
import { reactive, onMounted, toRefs } from 'vue'
import { useStore } from 'vuex'

export default function useRecaptcha () {
    const { executeRecaptcha: _executeRecaptcha, recaptchaLoaded } = useReCaptcha()
    const store = useStore()
    const state = reactive({
        // SDK 加载中
        loading: false,
        // SDK 加载完成
        loaded: false
    })

    onMounted(async () => {
        try {
            state.loading = true
            // 初始化 Google reCAPTCHA SDK
            const res = await recaptchaLoaded()
            if (res) {
                state.loaded = true
            }
        } catch (error) {
            console.log('🚀 ~ onMounted ~ error:', error)
        } finally {
            state.loading = false
        }
    })

    // 获取 Google reCAPTCHA 验证码
    const executeRecaptcha = async () => {
        try {
            const captcha = await _executeRecaptcha('verifyCodeSend')
            await store.commit('_base/UPDATE_captcha', captcha)
            return captcha
            // 更新全局 captcha 数据
        } catch (error) {
            console.log('🚀 ~ executeRecaptcha ~ error:', error)
        }
    }

    return {
        ...toRefs(state),
        executeRecaptcha,
        recaptchaLoaded
    }
}


```
3. 在 vuex store 定义captcha全局数据
```
// src/store/modules/base.js
export default {
   state: { 
      // Google 人机验证 captcha
      captcha: ''
   },
   mutations: {
      // 更新 Google 人机验证 captcha
      UPDATE_captcha (state, data) {
         state.captcha = data
      },
   }
}

```
4. axios拦截器添加错误提示
```
service.interceptors.response.use(
   response => {
      const { data } = response
      if (data.code === 'F999999') {
         // 提示文案需要做多语言处理
         Toast('请求参数不合法')
         return data
      }
      return response
   },
   error => {
      return Promise.reject(error)
   }
)
```
5. 使用示例
```


/** 第一步：引入 useRecaptcha hook   **/
const { executeRecaptcha } = useRecaptcha()


/** 第二步：在发送验证码接口头部添加 captcha 参数   **/
// 发送验证码 
export function verifyCodeSendRequest (data) {
    return request({
        url: '/global/message.app.VerificationApiService.verifyCodeSend',
        method: 'post',
        headers: {
            version: '0.0.1',
            // 请求头添加 google 验证码
            captcha: window.store.state._base.captcha
        },
        data
    })
}

/** 第三步：在需要添加 captcha 参数的接口前面执行executeRecaptcha  **/

// 发送验证码  message.app.VerificationApiService.verifyCodeSend
const verifyCodeSend = async () =>{
 await executeRecaptcha('verifyCodeSend') 
 await verifyCodeSendRequest()
}

// 登录 login/customer.app.CustomerWebApiService.login
const login= async () =>{
 await executeRecaptcha('login') 
 await loginRequest()
}

// 注册接口：register/customer.app.CustomerWebApiService.register
const register = async () =>{
 await executeRecaptcha('register') 
 await registerRequest()
}
```

````


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs-cn.multimarkets.org/client-api/shou-quan-fang-wen/ren-ji-jiao-yan.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
