這邊我採用 ARCANEDEV/noCAPTCHA 套件安裝,依照其安裝說明參考版本對照安裝正確版本,目前我採用 Laravel 6.x LTS 所以是 10.x 版,執行下面指令:

composer require arcanedev/no-captcha "10.x"

至 Google reCaptcha 取得 site key 及 secret key,然後將 site key 及 secret key 寫入 .env 檔案中:

        NOCAPTCHA_SITEKEY = your site key
        NOCAPTCHA_SECRET = your secret key

修改 config/app.php,在 providers 段落加入,Lavravel 版本大於等於 5.5 可以跳過。

        'providers' => [
            //Google reCaptcha 套件(Arcanedev\No-Captcha)
            Arcanedev\NoCaptcha\NoCaptchaServiceProvider::class,
        ],

執行 vendor:publish 產生 no-captcha.php 設定檔。

php artisan vendor:publish --provider="Arcanedev\NoCaptcha\NoCaptchaServiceProvider"

編輯 config\no-captcha.php 檔案設定 site key 與 site secret 及 版本。

        //採用 .env 設定,不需要修改
        'secret'  => env('NOCAPTCHA_SECRET', 'no-captcha-secret'),
        'sitekey' => env('NOCAPTCHA_SITEKEY', 'no-captcha-sitekey'),

        //預設 V3 (無勾選框) 改為 V2 (有勾選框)
        'version' => 'v2',

前端使用方法,在任何需要的表單中加入。將 {!! no_captcha()->display() !!} 放在<form></form>之間。 {!! no_captcha()->script()->toHtml() !!} 可以放在其他地方。我習慣是放在一起。

<div>
    {!! no_captcha()->script()->toHtml() !!}
    {!! no_captcha()->display() !!}
</div>

後端 controller 作法

use Arcanedev\NoCaptcha\Rules\CaptchaRule;

$inputs   = Input::all();
$rules    = [
    // Other validation rules...
    'g-recaptcha-response' => ['required', new CaptchaRule],
];
$messages = [
    'g-recaptcha-response.required' => 'Your custom validation message.',
    'g-recaptcha-response.captcha'  => 'Your custom validation message.',
];

$validator = Validator::make($inputs, $rules, $messages);

if ($validator->fails()) {
    $errors = $validator->messages();

    var_dump($errors->first('g-recaptcha-response'));

    // Redirect back or throw an error
}

修改 resources/lang/en/validation.php 或 其他版本 語言訊息

        return [
            // 驗證失敗時的訊息
            'captcha'   => "If you read this message, then you're a robot.",
        ];
        //放在 custom 若使用者未勾選顯示的訊息
        'custom' => [
            'g-recaptcha-response' => [
                'required' => 'Your custom validation message for captchas.',
            ],
        ],

我的登入表單 LoginController.php 範例

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Arcanedev\NoCaptcha\Rules\CaptchaRule;
use Auth;
class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
    //登入
    public function login(Request $request)
    {
        // 驗證表單資料
        $this->validate($request, [
            'email'   => 'required|email',
            'password' => 'required|min:4',
            'g-recaptcha-response' => ['required', new CaptchaRule],
        ]);
        // 將表單資料送去Auth::gurard('admin')驗證
        if (Auth::guard('user')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) {
            //驗證無誤轉入 index
            return redirect()->intended(route('index'));
        }
        // 驗證失敗 返回並拋出表單內容 只拋出 email 與 remember 欄位資料,
        // withErrors(['email' => trans('auth.failed')])用來覆蓋掉email欄位的錯誤訊息
        // trans('auth.failed) 系統預設語言拋出
        // 訊息 [使用者名稱或密碼錯誤] 為了不讓別人知道到底帳號是否存在
        return redirect()->back()->withInput($request->only('email', 'remember'))->withErrors(['email' => trans('auth.failed')]);
    }
}
最後修改日期: 2020 年 9 月 18 日