最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use google recaptcha in nuxt? - Stack Overflow

programmeradmin1浏览0评论

I am using nuxt and would like to use this library: . But I don't understand how to verify that the user has passed the check. The example doesn't tell me too much (.vue). Could someone show me how to do it correctly?

I am using nuxt and would like to use this library: 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). Could someone show me how to do it correctly?

Share Improve this question asked Aug 25, 2020 at 20:19 user14166158user14166158
Add a comment  | 

3 Answers 3

Reset to default 5

This example is only half the story. It returns a Recaptcha V3 token on the client-side.

This must then be sent to the serverside and verified using your secret key.

This is done by sending a post to this URL:

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

You do not want to allow this secret key on the client side.

To achieve this in Nuxt, assuming version 2.13+, you can utilise privateRuntimeConfig in your nuxt config.

This will allow you to link a .env file to be injected only on the server side.

For this use case, a privateRuntimeConfig like this should suffice:

privateRuntimeConfig: {
    secretKey: process.env.GOOGLE_SECRET
}

Once you have done this, you will be able to access these variables as part of this.$config within your Nuxt application - in this case this.$config.secretKey when calling the Recaptcha verify endpoint.

For more information check out the Nuxt blog

Use https://github.com/nuxt-community/recaptcha-module, in your 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
},

Keep in mind that modules, that's not the same as buildModules (sometimes it might confuse due to similar naming).

Here is a working implementation for ReCaptcha V3:

package.json

  "dependencies": {
    "@nuxtjs/axios": "^5.13.6",
    "@nuxtjs/recaptcha": "^1.0.4",
    "h3": "^0.3.9",
  },

Note the h3 version. I wasn't able to get it working with a newer version of that because the library is converted to EJS/mjs and TypeScript, which conflicts with Nuxt. Transpiling h3 didn't fix it. It may work with 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
        }
    },
},

You can read more here: https://www.npmjs.com/package/@nuxtjs/recaptcha

Note the section where it says

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)

The above server-side middleware comes from there. It is important to use the version of h3 that I suggest because you need it to access useBody(req). I tried for several hours to find another way to read the request body but it proved too difficult. Your results may vary in a newer version of Nuxt. I suggest trying the newest version of h3 and if that fails with errors when building the application, try the older version.

It is critically important to not expose the ReCaptcha secret key, and this solution keeps it secret in the server-side.

A more optimal solution might be to use your actual server and make an endpoint for validating ReCaptcha tokens. This above solution allows you to do it purely client-side, assuming you are using SSR.

发布评论

评论列表(0)

  1. 暂无评论