如何在 nuxt 中使用 google recaptcha?

问题描述 投票:0回答:4

我正在使用 nuxt 并且想使用这个库:https://github.com/nuxt-community/recaptcha-module。但我不明白如何验证用户是否通过了检查。这个例子并没有告诉我太多(https://github.com/nuxt-community/recaptcha-module/blob/master/example/v3/pages/index.vue)。有人可以告诉我如何正确地做吗?

javascript vue.js recaptcha
4个回答
5
投票

这个例子只是故事的一半。它在客户端返回 Recaptcha V3 令牌。

然后必须将其发送到服务器端并使用您的密钥进行验证。

这是通过向此 URL 发送帖子来完成的:

const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${token}`;

您不想在客户端允许此密钥。

要在 Nuxt 中实现此目的,假设版本为 2.13+,您可以在 nuxt 配置中使用

privateRuntimeConfig

这将允许您链接仅在服务器端注入的 .env 文件。

对于这个用例,像这样的 privateRuntimeConfig 应该足够了:

privateRuntimeConfig: {
    secretKey: process.env.GOOGLE_SECRET
}

完成此操作后,您将能够在 Nuxt 应用程序中作为

this.$config
的一部分访问这些变量 - 在本例中为
this.$config.secretKey
当调用 Recaptcha 验证端点时。

了解更多信息查看 Nuxt 博客


3
投票

在您的 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
相同(有时可能会因相似的命名而造成混淆)。


2
投票

这是 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' },
  ],

中间件/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

注意它所说的部分

服务器端 当您向服务器发送数据+令牌时,您应该在服务器端验证令牌以确保它不是从机器人请求的。您可以通过查看 v2 示例中的服务器中间件来了解如何在服务器端验证令牌。 (两个版本的服务器端相同)

上面的服务器端中间件就来自那里。使用我建议的

h3
版本非常重要,因为您需要它来访问
useBody(req)
。我尝试了几个小时来寻找另一种读取请求正文的方法,但事实证明这太困难了。在较新版本的 Nuxt 中,您的结果可能会有所不同。我建议尝试最新版本的
h3
,如果在构建应用程序时失败并出现错误,请尝试旧版本。

不要暴露 ReCaptcha 密钥至关重要,该解决方案在服务器端对其保密。

更佳的解决方案可能是使用您的实际服务器并创建一个端点来验证 ReCaptcha 令牌。假设您使用的是 SSR,上述解决方案允许您纯粹在客户端执行此操作。


0
投票
是否可以仅在客户端通过验证码检查令牌?

© www.soinside.com 2019 - 2024. All rights reserved.