首页 > 解决方案 > 如何将 Recaptcha v2 添加到 Laravel 和 Vue js?

问题描述

我正在关注这篇关于如何将 Recaptcha v2 添加到 Laravel 和 Vue js 项目的文章。 https://www.itechempires.com/2018/05/how-to-implement-google-recapcha-with-vuejs-and-laravel-5-6/

我正在尝试在我的项目中实现它,但我在页面上收到此错误:

The recaptcha verification failed. Try again.

在网络选项卡中出现此错误:

{recaptcha: ["The recaptcha verification failed. Try again."]}

在控制台中:

POST http://highrjobsadminlte.test/submit 422 (Unprocessable Entity)

我正在尝试在我的 Contact.vue 页面上的联系表单上实现这一点。

联系方式:

<form @submit.prevent="submit">
                        <div class="form-group">
                            <label for="name">Name</label>
                            <input type="text" class="form-control" name="name" id="name" v-model="fields.name" />
                            <div v-if="errors && errors.name" class="text-danger" style="font-size: 13px;">{{ errors.name[0] }}</div>
                        </div>

                        <div class="form-group">
                            <label for="email">E-mail</label>
                            <input type="email" class="form-control" name="email" id="email" v-model="fields.email" />
                            <div v-if="errors && errors.email" class="text-danger" style="font-size: 13px;">{{ errors.email[0] }}</div>
                        </div>

                        <div class="form-group">
                            <label for="message">Message</label>
                            <textarea class="form-control" id="message" name="message" rows="5" v-model="fields.message"></textarea>
                            <div v-if="errors && errors.message" class="text-danger" style="font-size: 13px;">{{ errors.message[0] }}</div>
                        </div>

                        <div class="form-group">
                            <vue-recaptcha
                                v-model="fields.recaptcha"
                                ref="recaptcha"
                                @verify="onVerify"
                                sitekey="6LcAHcoZAAAAAFDOejn9e2LrogSpF41RMlXtrpDa">
                            </vue-recaptcha>
                        </div>
                        <div v-if="errors && errors.recaptcha" class="text-danger" style="font-size: 13px;">{{ errors.recaptcha[0] }}</div>

                        <button type="submit" class="btn btn-primary mt-3">Send message</button>
                    </form>
export default {
        name: "Contact",

        data() {
            return {
                fields: {},
                errors: {},
            }
        },

        methods: {
            onVerify(response) {
                this.fields.recaptcha = response;
            },
            submit() {
                this.errors = {};
                axios.post('/submit', this.fields, {
                    headers:{
                        'Content-Type':'application/json',
                        'Accept':'application/json'
                    }
                }).then(({data: {fields}}) => {
                    this.$toast.success('Message sent successfully!');
                    this.$refs.recaptcha.reset();
                }).catch(error => {
                    if (error) {
                        this.errors = error.response.data.errors || {};
                    }
                });
            },
        },
    }

Recaptcha.php(这是一条规则):

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use Zttp\Zttp;

class Recaptcha implements Rule
{
    const URL = 'https://www.google.com/recaptcha/api/siteverify';

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return Zttp::asFormParams()->post(static::URL, [
            'secret' => config('services.recaptcha.secret'),
            'response' => $value,
            'remoteip' => request()->ip()
        ])->json()['success'];
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The recaptcha verification failed. Try again.';
    }

    /**
     * Determine if Recaptcha's keys are set to test mode.
     *
     * @return bool
     */
    public static function isInTestMode()
    {
        return Zttp::asFormParams()->post(static::URL, [
            'secret' => config('services.recaptcha.secret'),
            'response' => 'test',
            'remoteip' => request()->ip()
        ])->json()['success'];
    }
}

ContactFormController.php:

<?php

namespace App\Http\Controllers;

use App\Mail\ContactEmail;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Rules\Recaptcha;

class ContactFormController extends Controller
{
    public function submit(Request $request, Recaptcha $recaptcha) {

        $this->validate($request, [
            'name' => 'required|string',
            'email' => 'required|email',
            'message' => 'required',
            'recaptcha' => ['required', $recaptcha],
        ]);

        $contact = [];

        $contact['name'] = $request->get('name');
        $contact['email'] = $request->get('email');
        $contact['subject'] = $request->get('subject');
        $contact['message'] = $request->get('message');

        // Mail Delivery logic goes here
        Mail::to(config('mail.from.address'))->send(new ContactEmail($contact));

        return response(['contact' => $contact], 200);
    }

}

网页.php:

Route::post('/submit', 'ContactFormController@submit');

我已经在 config/services.php 中设置了 recaptcha 密钥和秘密,以指向我的 .env 变量,这些变量在我的 .env 文件中设置。

标签: laravelvue.jsrecaptcha

解决方案


推荐阅读