在逛 CloudFlare 的时候看到了 Turnstile,觉得好奇就去看了下文档才知道它是 CloudFlare 家的人机验证,刚好部署了图床管理就想着能不能试试接入它,做下记录。
1. 创建 Turnstile 组件
在 src/components 目录中创建一个新的 Turnstile 组件,比如 Turnstile.vue
:
<template>
<div>
<div id="cf-turnstile" :data-sitekey="siteKey"></div>
</div>
</template>
<script setup lang="ts">
import {onMounted, ref} from "vue";
const props = defineProps<{
sitekey: {
type: String,
required: true
}
}>()
const turnstileResponse = ref<string>('')
const emit = defineEmits(['getTurnstileResponse'])
onMounted(() => {
loadTurnstileScript()
})
const loadTurnstileScript = () => {
const script = document.createElement('script');
script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback';
script.async = true;
script.defer = true;
document.head.appendChild(script);
script.onload = () => {
setupTurnstileCallback();
};
}
const setupTurnstileCallback = () => {
window.onloadTurnstileCallback = () => {
window.turnstile?.render("#cf-turnstile", {
sitekey: props.sitekey,
callback: handleTurnstileSuccess
});
};
}
const handleTurnstileSuccess = (token: String) => {
turnstileResponse.value = token
emit('getTurnstileResponse', turnstileResponse)
}
</script>
<style scoped>
</style>
2. 使用 Turnstile 组件并验证响应
在你的主组件(例如 App.vue 或者其他组件)中使用 Turnstile 组件,并处理表单提交和 Turnstile 验证:
<template>
<div id="app">
<form @submit.prevent="handleSubmit">
<Turnstile @getTurnstileResponse="getTurnstileResponse" :siteKey="siteKey" />
<button type="submit">Submit</button>
</form>
</div>
</template>
<script>
import axios from 'axios';
import Turnstile from './components/Turnstile.vue';
const siteKey = ref('your-site-key')
// 获取子组件值
const turnstileResponse = ref<string>('')
const getTurnstileResponse = (value: string) => {
turnstileResponse.value = value
}
const handleSubmit = () => {
try {
const response = await axios.post('/verify-turnstile', {
response: turnstileResponse.value._value
});
if (response.data.success) {
alert('Verification successful!');
} else {
alert('Verification failed!');
}
} catch (error) {
console.error('Error during Turnstile verification:', error);
alert('Verification error!');
}
}
</script>
3. 服务器端验证 Turnstile 响应
在服务器端处理 Turnstile 响应验证。以下是使用 Node.js 和 Express 的示例:
const express = require('express');
const bodyParser = require('body-parser');
const axios = require('axios');
const app = express();
app.use(bodyParser.json());
app.post('/verify-turnstile', async (req, res) => {
const turnstileResponse = req.body.response;
const secretKey = 'your-secret-key';
try {
let formData = new FormData();
formData.append('secret', secretKey);
formData.append('response', turnstileResponse);
const verifyUrl = 'https://challenges.cloudflare.com/turnstile/v0/siteverify'
const verificationResponse = await fetch(verifyUrl, {
method: 'POST',
body: formData
})
const verificationResult = await verificationResponse.json();
if (verificationResult.success) {
res.json({ success: true });
} else {
res.json({ success: false });
}
} catch (error) {
console.error('Error during Turnstile verification:', error);
res.status(500).json({ success: false });
}
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
4. 运行和测试
启动你的服务器和 Vue 项目,确保一切正常。你现在应该可以在浏览器中访问你的应用程序,看到 Turnstile 验证并进行表单提交。
通过以上步骤,你可以在 Vue 3 项目中集成 Cloudflare Turnstile,增强表单的安全性。确保在实际应用中使用正确的密钥和配置,以最大程度地提高安全性和可靠性。
...