【发布时间】:2018-12-18 12:20:42
【问题描述】:
是否有任何简单的方法可以在 react 中使用 reCAPTCHA v3?谷歌搜索只能找到 v2 的组件。并且只有 react-recaptcha-v3 用于 v3。
但是当我尝试使用该组件时,我收到一个错误 Invalid site key or not loaded in api.js。
【问题讨论】:
-
你能发布你的实现代码吗?
是否有任何简单的方法可以在 react 中使用 reCAPTCHA v3?谷歌搜索只能找到 v2 的组件。并且只有 react-recaptcha-v3 用于 v3。
但是当我尝试使用该组件时,我收到一个错误 Invalid site key or not loaded in api.js。
【问题讨论】:
嘿,你不需要一个包,它只是一个你不需要的不必要的包。 https://medium.com/@alexjamesdunlop/unnecessary-packages-b3623219d86 我写了一篇关于为什么你不应该使用它和另一个包的文章。 不要依赖某些软件包!改用谷歌:)
const handleLoaded = _ => {
window.grecaptcha.ready(_ => {
window.grecaptcha
.execute("_reCAPTCHA_site_key_", { action: "homepage" })
.then(token => {
// ...
})
})
}
useEffect(() => {
// Add reCaptcha
const script = document.createElement("script")
script.src = "https://www.google.com/recaptcha/api.js?render=_reCAPTCHA_site_key"
script.addEventListener("load", handleLoaded)
document.body.appendChild(script)
}, [])
return (
<div
className="g-recaptcha"
data-sitekey="_reCAPTCHA_site_key_"
data-size="invisible"
></div>
)
【讨论】:
handleLoaded 和then 中将代码发送到服务器。同样在UseEffect 不要写这行script.addEventListener("load", handleLoaded)
我正在自学 React + TypeScript,这就是我实现 recaptcha v3 的方法。
我想要一个简单的解决方案,让我能够:
reCAPTCHA.ts
declare global {
interface Window {
grecaptcha: any;
}
}
export default class reCAPTCHA {
siteKey: string;
action: string;
constructor(siteKey: string, action: string) {
loadReCaptcha(siteKey);
this.siteKey = siteKey;
this.action = action;
}
async getToken(): Promise<string> {
let token = "";
await window.grecaptcha.execute(this.siteKey, {action: this.action})
.then((res: string) => {
token = res;
})
return token;
}
}
const loadReCaptcha = (siteKey: string) => {
const script = document.createElement('script')
script.src = `https://www.recaptcha.net/recaptcha/api.js?render=${siteKey}`
document.body.appendChild(script)
}
要使用此类,请将其声明为组件中的属性:
recaptcha = new reCAPTCHA((process.env.REACT_APP_RECAPTCHA_SITE_KEY!), "login");
并在表单提交时获取您需要传递给后端的令牌:
let token: string = await this.recaptcha.getToken();
在后端验证令牌:
recaptcha.ts
const fetch = require("node-fetch");
const threshold = 0.6;
export async function validateRecaptcha(recaptchaToken: string, expectedAction: string) : Promise<boolean> {
const recaptchaSecret = process.env.RECAPTCHA_SECRET_KEY;
const url = `https://www.recaptcha.net/recaptcha/api/siteverify?secret=${recaptchaSecret}&response=${recaptchaToken}`;
let valid = false;
await fetch(url, {method: 'post'})
.then((response: { json: () => any; }) => response.json())
.then((data: any)=> {
valid = (data.success && data.score && data.action && data.score >= threshold && data.action === expectedAction);
});
return valid;
}
我在 JS/TS 和 React 方面的经验非常有限,但这个解决方案确实对我有用。我欢迎任何有关改进此代码的意见。
【讨论】:
试试这个! https://github.com/t49tran/react-google-recaptcha-v3 npm install react-google-recaptcha-v3
【讨论】:
您可以使用react-google-recaptcha3 npm 包(大小:~5 KB)
npm i react-google-recaptcha3
用法
import ReactRecaptcha3 from 'react-google-recaptcha3';
const YOUR_SITE_KEY = '';
function App() {
// load google recaptcha3 script
useEffect(() => {
ReactRecaptcha3.init(YOUR_SITE_KEY).then(
(status) => {
console.log(status);
}
);
}, [])
}
现在在提交表单时,您需要生成令牌,然后将其附加到您的表单数据中
const submit = () => {
const formData = { name: "John", lastname: "Doe" }
ReactRecaptcha3.getToken().then(
(token) => {
console.log(token);
formData.token = token;
// send request to backend
fetch(url, { method: 'POST', body: JSON.stringify(formData) }).then(...)
},
(error) => {
console.log(error);
}
);
};
现在在后端你需要验证令牌
const request = require('request-promise');
const secretKey = YOUR_RECAPTCHA_SECRET_KEY;
const userIp = 'USER_IP';
request.get({
url: `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${recaptchaToken}&remoteip=${userIp}`,
}).then((response) => {
// If response false return error message
if (response.success === false) {
return res.json({
success: false,
error: 'Recaptcha token validation failed'
});
}
// otherwise continue handling/saving form data
next();
})
【讨论】: