如何在nuxt中使用google recaptcha?
How to use google recaptcha in nuxt?
我正在使用 nuxt 并且想使用这个库:https://github.com/nuxt-community/recaptcha-module. But I don't understand how to verify that the user has passed the check. The example doesn't tell me too much (https://github.com/nuxt-community/recaptcha-module/blob/master/example/v3/pages/index.vue)。有人可以告诉我如何正确地做吗?
这个例子只是故事的一半。它 returns client-side 上的 Recaptcha V3 令牌。
然后必须将其发送到服务器端并使用您的密钥进行验证。
这是通过向 URL 发送一个 post 来完成的:
const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${token}`;
您不想在客户端允许此密钥。
要在 Nuxt 中实现这一点,假设版本为 2.13+,您可以在 nuxt 配置中使用 privateRuntimeConfig
。
这将允许您 link 仅在服务器端注入 .env 文件。
对于这个用例,像这样的 privateRuntimeConfig 就足够了:
privateRuntimeConfig: {
secretKey: process.env.GOOGLE_SECRET
}
完成此操作后,您将能够在 Nuxt 应用程序中作为 this.$config
的一部分访问这些变量 - 在本例中 this.$config.secretKey
调用 Recaptcha 验证端点时。
在您的 nuxt.config.js
中使用 https://github.com/nuxt-community/recaptcha-module
modules: [
'@nuxtjs/recaptcha',
],
recaptcha: {
hideBadge: true,
siteKey: "ABC...", // Better would be from 'process.env.API_KEY' and with '.env' file
version: 2, // Or 3
},
请记住 modules
,与 buildModules
不同(有时由于相似的命名可能会混淆)。
这是 ReCaptcha V3 的有效实现:
package.json
"dependencies": {
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/recaptcha": "^1.0.4",
"h3": "^0.3.9",
},
注意 h3
版本。我无法让它与更新版本一起使用,因为该库已转换为 EJS/mjs 和 TypeScript,这与 Nuxt 冲突。转译 h3
没有修复它。它可能适用于 Nuxt V3+。
nuxt.config.js
modules: [
['@nuxtjs/recaptcha', {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
}],
],
serverMiddleware: [
{ path: '/api/check-token', handler: '~/middleware/recaptcha' },
],
middleware/recaptcha.js
import { useBody } from 'h3';
import axios from 'axios';
export default async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const { token } = await useBody(req);
if (!token) {
res.end(
JSON.stringify({
success: false,
message: 'Invalid token'
})
);
return;
}
axios.get(`https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${token}`).then((answer) => {
if (answer.status) {
res.end(
JSON.stringify({
success: true,
message: 'Token verified'
})
);
} else {
res.end(
JSON.stringify({
success: false,
message: 'Invalid token'
})
);
}
});
} catch (e) {
console.log('ReCaptcha error:', e);
res.end(
JSON.stringify({
success: false,
message: 'Internal error'
})
);
}
};
.env
RECAPTCHA_SITE_KEY=gosei478htosvei478tvoei478tvge
RECAPTCHA_SECRET_KEY=ios47eos487t6es4897gtv6es487
index.vue
async mounted() {
try {
await this.$recaptcha.init();
} catch (err) {
throw new Error(`index# Problem initializing ReCaptcha: ${err}.`);
}
},
beforeDestroy() {
this.$recaptcha.destroy();
},
methods: {
async submitContactForm() {
try {
const token = await this.$recaptcha.execute('contact')
const formData = {
email: this.contactForm.email,
firstname: name.firstName,
lastname: name.lastName,
phone: this.contactForm.phone,
band_name: this.contactForm.band_name,
initial_message: this.contactForm.message,
}
// note: use POST request
const recaptcha = await this.$axios.post('/api/check-token', { token });
console.log('recaptcha', recaptcha.data);
if (recaptcha.data.success) {
const result = await this.$axios.post(process.env.CONTACT_FORM_API, formData);
// cleanup logic
} else {
// handle error case
}
} catch (err) {
// handle errors
}
},
},
您可以在此处阅读更多内容:https://www.npmjs.com/package/@nuxtjs/recaptcha
注意它所说的部分
Server Side
When you send data + token to the server, you should verify the token on the server side to make sure it does not requested from a bot. You can find out how to verify token on the server side by looking at the server middleware inside v2 example. (The server side is same for both versions)
上面的server-side中间件就出自那里。使用我建议的 h3
版本很重要,因为您需要它来访问 useBody(req)
。我尝试了几个小时来寻找另一种方法来阅读请求正文,但事实证明这太难了。在较新版本的 Nuxt 中,您的结果可能会有所不同。我建议尝试使用最新版本的 h3
,如果在构建应用程序时失败并出现错误,请尝试使用旧版本。
不 暴露 ReCaptcha 密钥非常重要,此解决方案将其保密在 server-side.
更好的解决方案可能是使用您的实际服务器并创建一个端点来验证 ReCaptcha 令牌。假设您使用的是 SSR,上述解决方案允许您纯粹 client-side。
我正在使用 nuxt 并且想使用这个库:https://github.com/nuxt-community/recaptcha-module. But I don't understand how to verify that the user has passed the check. The example doesn't tell me too much (https://github.com/nuxt-community/recaptcha-module/blob/master/example/v3/pages/index.vue)。有人可以告诉我如何正确地做吗?
这个例子只是故事的一半。它 returns client-side 上的 Recaptcha V3 令牌。
然后必须将其发送到服务器端并使用您的密钥进行验证。
这是通过向 URL 发送一个 post 来完成的:
const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${token}`;
您不想在客户端允许此密钥。
要在 Nuxt 中实现这一点,假设版本为 2.13+,您可以在 nuxt 配置中使用 privateRuntimeConfig
。
这将允许您 link 仅在服务器端注入 .env 文件。
对于这个用例,像这样的 privateRuntimeConfig 就足够了:
privateRuntimeConfig: {
secretKey: process.env.GOOGLE_SECRET
}
完成此操作后,您将能够在 Nuxt 应用程序中作为 this.$config
的一部分访问这些变量 - 在本例中 this.$config.secretKey
调用 Recaptcha 验证端点时。
在您的 nuxt.config.js
modules: [
'@nuxtjs/recaptcha',
],
recaptcha: {
hideBadge: true,
siteKey: "ABC...", // Better would be from 'process.env.API_KEY' and with '.env' file
version: 2, // Or 3
},
请记住 modules
,与 buildModules
不同(有时由于相似的命名可能会混淆)。
这是 ReCaptcha V3 的有效实现:
package.json
"dependencies": {
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/recaptcha": "^1.0.4",
"h3": "^0.3.9",
},
注意 h3
版本。我无法让它与更新版本一起使用,因为该库已转换为 EJS/mjs 和 TypeScript,这与 Nuxt 冲突。转译 h3
没有修复它。它可能适用于 Nuxt V3+。
nuxt.config.js
modules: [
['@nuxtjs/recaptcha', {
siteKey: process.env.RECAPTCHA_SITE_KEY,
version: 3,
}],
],
serverMiddleware: [
{ path: '/api/check-token', handler: '~/middleware/recaptcha' },
],
middleware/recaptcha.js
import { useBody } from 'h3';
import axios from 'axios';
export default async (req, res) => {
res.setHeader('Content-Type', 'application/json');
try {
const { token } = await useBody(req);
if (!token) {
res.end(
JSON.stringify({
success: false,
message: 'Invalid token'
})
);
return;
}
axios.get(`https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET_KEY}&response=${token}`).then((answer) => {
if (answer.status) {
res.end(
JSON.stringify({
success: true,
message: 'Token verified'
})
);
} else {
res.end(
JSON.stringify({
success: false,
message: 'Invalid token'
})
);
}
});
} catch (e) {
console.log('ReCaptcha error:', e);
res.end(
JSON.stringify({
success: false,
message: 'Internal error'
})
);
}
};
.env
RECAPTCHA_SITE_KEY=gosei478htosvei478tvoei478tvge
RECAPTCHA_SECRET_KEY=ios47eos487t6es4897gtv6es487
index.vue
async mounted() {
try {
await this.$recaptcha.init();
} catch (err) {
throw new Error(`index# Problem initializing ReCaptcha: ${err}.`);
}
},
beforeDestroy() {
this.$recaptcha.destroy();
},
methods: {
async submitContactForm() {
try {
const token = await this.$recaptcha.execute('contact')
const formData = {
email: this.contactForm.email,
firstname: name.firstName,
lastname: name.lastName,
phone: this.contactForm.phone,
band_name: this.contactForm.band_name,
initial_message: this.contactForm.message,
}
// note: use POST request
const recaptcha = await this.$axios.post('/api/check-token', { token });
console.log('recaptcha', recaptcha.data);
if (recaptcha.data.success) {
const result = await this.$axios.post(process.env.CONTACT_FORM_API, formData);
// cleanup logic
} else {
// handle error case
}
} catch (err) {
// handle errors
}
},
},
您可以在此处阅读更多内容:https://www.npmjs.com/package/@nuxtjs/recaptcha
注意它所说的部分
Server Side When you send data + token to the server, you should verify the token on the server side to make sure it does not requested from a bot. You can find out how to verify token on the server side by looking at the server middleware inside v2 example. (The server side is same for both versions)
上面的server-side中间件就出自那里。使用我建议的 h3
版本很重要,因为您需要它来访问 useBody(req)
。我尝试了几个小时来寻找另一种方法来阅读请求正文,但事实证明这太难了。在较新版本的 Nuxt 中,您的结果可能会有所不同。我建议尝试使用最新版本的 h3
,如果在构建应用程序时失败并出现错误,请尝试使用旧版本。
不 暴露 ReCaptcha 密钥非常重要,此解决方案将其保密在 server-side.
更好的解决方案可能是使用您的实际服务器并创建一个端点来验证 ReCaptcha 令牌。假设您使用的是 SSR,上述解决方案允许您纯粹 client-side。