[擴充套件推薦] 使用 laravel-gridCaptcha 本地生成類似於谷歌點圖驗證碼

dabao_asda發表於2021-10-04

介紹

laravel-gridCaptcha 生成類似於谷歌點圖驗證碼的小擴充套件,因為現在PHP大部分生成的驗證碼,對於惡意者來說很容易識別,而這套小擴充套件很簡單但是對於機器人來說需要進行深度的機器學習,惡意者攻擊的成本也就增加了,但是這套小擴充套件不同於谷歌驗證碼需要機器學習,只需要在本地配置好相應的檔案即可。因為生成的驗證碼圖片都是讀取檔案進行生成,所以建議使用Redis進行快取,程式碼預設有使用快取。

ps: 如有不足之處,歡迎大佬提出修改意見。

Github

Packagist

預覽

Preview

安裝

支援 Laravel 8 以上版本:

 composer require deletedb/laravel-captcha-grid

配置項說明

  • 釋出配置檔案
php artisan vendor:publish --provider="Deletedb\Laravel\Providers\LaravelServiceProvider"
config/gridcaptcha.php
return [
    //生成驗證碼圖片配置
    'image' => [
        //驗證碼圖片路徑
        'path' => env('GRID_CAPTCHA_IMAGE_PATH', storage_path('gridcaptcha\image')),
        //從驗證碼圖片路徑中獲取的檔案字尾名
        'suffix' => env('GRID_CAPTCHA_IMAGE_SUFFIX', 'jpg'),
        //生成驗證碼質量
        'quality' => env('GRID_CAPTCHA_IMAGE_QUALITY', 70),
        //生產驗證碼寬
        'wide' => env('GRID_CAPTCHA_IMAGE_WIDE', 300),
        //生產驗證碼高
        'high' => env('GRID_CAPTCHA_IMAGE_HIGH', 300),
    ],
    //驗證碼配置
    'captcha' => [
        //生成的驗證碼過期時間 單位秒
        'validity' => env('GRID_CAPTCHA_IMAGE_VALIDITY', 180),
        //驗證碼快取的key
        'cache_key' => env('GRID_CAPTCHA_IMAGE_CACHE_KEY', 'grid_captcha'),
        //驗證碼生成的key長度
        'key_length' => env('GRID_CAPTCHA_IMAGE_KEY_LENGTH', 64),
        //自定義效驗驗證碼key欄位
        'key_string' => env('GRID_CAPTCHA_IMAGE_KEY_STRING', 'captcha_key'),
        //自定義效驗驗證碼code欄位
        'code_string' => env('GRID_CAPTCHA_IMAGE_CODE_STRING', 'captcha_code'),
    ],
];

使用

  • 生成驗證碼

    <?php
    namespace App\Http\Controllers;
    class TestController extends Controller
    {
      /**
       * 輔助函式生成驗證碼
       * @return array
       */
      public function helpers()
      {
          return grid_captcha([
              'mobile' => '100xxxxx121'
          ]);
      }
    
      /**
       * 門面方式生成驗證碼
       * @return array
       */
      public function facade()
      {
          return \Deletedb\Laravel\Facades\GridCaptcha::get([
              'mobile' => '100xxxxx121'
          ]);
      }
    
      /**
       * 物件方式生成驗證碼
       * @return array
       */
      public function object()
      {
          $captcha = new \Deletedb\Laravel\GridCaptcha();
          return $captcha->get([
              'mobile' => '100xxxxx121'
          ]);
      }
    }
    
- 生成結果

```json5
{
  "hint": "猴子",//提示文字
  "captcha_key": "Qh8kHYF4C....",//驗證碼key
  "image": "data:image/jpeg;base64,/9j/...."//base64驗證碼圖片 -- 前端渲染顯示
}
  • 效驗驗證碼
 <!--

生成的是一個九宮格圖片,前端需要渲染圖片,並且生成九個div用於記錄使用者點選的宮格位置,宮格位置從 0 開始,當點選到四位的時候返回給後端進行效驗 ,因為前端技術拙劣我就不放例子了歡迎大佬補充。

大概思路:
-->
<div>
    <!-- img 顯示的是返回的驗證碼圖片-->
    <img src="data:image/jpeg;base64...." width="300" height="300" alt="" style="display: block;">
    <div id="0"></div>
    <div id="1"></div>
    <div id="2"></div>
    <div id="3"></div>
    <div id="4"></div>
    <div id="5"></div>
    <div id="6"></div>
    <div id="7"></div>
    <div id="8"></div>
</div>
  • 效果:
    Preview
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TestController extends Controller
{

    /**
     * 輔助函式方式效驗
     * @param Request $request
     * @return array|false|\Illuminate\Http\JsonResponse
     */
    public function helpersCheck(Request $request)
    {
        /**
         * 傳參效驗
         */
        if ($captcha_data = grid_captcha()->check('Qh8kHYF4C....', '1540') === false) {
            return response()->json(['message' => '驗證碼錯誤', 'code' => 401]);
        }

        /**
         * 傳遞 Request 物件效驗
         */
        if ($captcha_data = grid_captcha()->checkRequest($request)) {
            return response()->json(['message' => '驗證碼錯誤', 'code' => 401]);
        }

        return $captcha_data;
    }

    /**
     * 門面方式效驗
     * @param Request $request
     * @return array|false|\Illuminate\Http\JsonResponse
     */
    public function facadeCheck(Request $request)
    {
        /**
         * 傳參效驗
         */
        if ($captcha_data = \Deletedb\Laravel\Facades\GridCaptcha::check('Qh8kHYF4C....', '1540') === false) {
            return response()->json(['message' => '驗證碼錯誤', 'code' => 401]);
        }

        /**
         * 傳遞 Request 物件效驗
         */
        if ($captcha_data = \Deletedb\Laravel\Facades\GridCaptcha::checkRequest($request)) {
            return response()->json(['message' => '驗證碼錯誤', 'code' => 401]);
        }

        return $captcha_data;
    }

    /**
     * 物件方式效驗
     * @param Request $request
     * @return array|false|\Illuminate\Http\JsonResponse
     */
    public function objectCheck(Request $request)
    {
        $captcha = new \Deletedb\Laravel\GridCaptcha();
        /**
         * 傳參效驗
         */
        if ($captcha_data = $captcha->check('Qh8kHYF4C....', '1540') === false) {
            return response()->json(['message' => '驗證碼錯誤', 'code' => 401]);
        }

        /**
         * 傳遞 Request 物件效驗
         */
        if ($captcha_data = $captcha->checkRequest($request)) {
            return response()->json(['message' => '驗證碼錯誤', 'code' => 401]);
        }

        return $captcha_data;
    }
}

    //效驗完成正確後 您可以進行業務邏輯處理,比如可以獲取到上方設定在驗證碼中的資料 如:上方設定的是手機號,您這裡可以獲取驗證碼中的手機號,當效驗成功傳送簡訊驗證碼等...
  • 效驗成功返回: 返回的是您在生成驗證時傳遞的資料,預設返回空陣列

  • 效驗失敗返回: false

    {
        "mobile" : "100xxxxx121"
    }
  • 本地化提示

    resources/lang/zh_CN/grid-captcha.php
    <?php
    //一個圖片目錄對應一個提示
    return [
      'banmaxian' => '斑馬線',
      'gongjiaoche' => '公交車',
      'heiban' => '黑板',
      'honglvdeng' => '紅綠燈',
      'hongzao' => '紅棗',
      'houzi' => '猴子',
      'qianbi' => '鉛筆',
      'shutiao' => '薯條',
      'xiaofangshuan' => '消防栓',
      'zhenglong' => '蒸籠',
    ];
  • 新增驗證碼圖片

    例:新增一個型別為 pingguo 驗證碼型別的圖片,需要在配置檔案中的 image.path 目錄下建立名為 pingguo 的目錄並且把相關型別的圖片檔案存放在 pingguo 目錄,新增一個型別至少要有四張相關型別的圖片,不限制檔名,只要檔案字尾名是配置檔案中指定的即可如下:

    ─storage
      └─gridcaptcha
          └─image
              ├─pingguo
              │       1.jpg
              │       10.jpg
              │       11.jpg
              │       12.jpg
              │       13.jpg
    

```

特別說明

因為讀取檔案是快取消耗I/O的操作所以我推薦使用Redis進行快取,此工具預設使用了快取,快取有當前驗證碼圖片目錄資訊、圖片;使用Redis快取只需要在 .env 檔案修改 CACHE_DRIVER=redis ,並且新增Redis配置即可;在新增新分類之後建議刪除之前的快取,如果不進行刪除將在快取過期後自動更新。

License

MIT

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章