Django Simple Captcha 驗證碼


建立時間: 2023年1月24日 16:14
更新時間: 2023年9月14日 08:41

說明

最近 Enjoy 軟體的聯絡我們表單一直被廣告訊息騷擾,我實在忍不住的,決定新增驗證碼來防止機器人的廣告訊息,據說驗證碼很好破解,但好處是程式碼是開源的,可以免費使用,如果真的被破解的話還有 Google 提供的 reCAPTCHA,雖然被破解的難度更高,但每個月使用次數有上限,雖然小網站不會用這麼多,但怕有一天 Google 會收費,所以起初先以簡單的 Django Simple Captcha 實作驗證碼就好

安裝

安裝方式請參考 Using django-simple-captcha Installation 官方文件,不會太複雜,按照步驟即可。

使用說明

這裡提供一種使用方式做為教學,大家可以依自己的需求而調整。

設定

考量我的表單可能需要花費比較多時間填寫,所以我把驗證碼的有效時間拉長

settings.py

# 驗證碼有效時間,單位分鐘
CAPTCHA_TIMEOUT = 60

在表單加入欄位

這裡舉例我要在 ContactForm 表單加入驗證碼

  • error_messages: 錯誤訊息提示
  • label: 欄位名稱

forms.py

from captcha.fields import CaptchaField

class ContactForm(Form):
    # 略
    captcha = CaptchaField(
        error_messages={
            'invalid': '驗證碼錯誤'
        },
        label='驗證碼'
    )

在此不會說明 Django 表單的細節,如果你不清楚如何實作表單的話可以參考我之前寫的 Django 實作 聯絡我們

AJAX 重新整理驗證碼

這裡貼心提供重新整理按鈕給使用者操作,當使用者看不懂驗證碼時可以即時地重新整理驗證碼,以下程式碼為原生的 Javascript 沒有使用 jQuery,但有使用 bootstrap 的 icon icon.classList.add('bi', 'bi-arrow-clockwise'),如果你不想安裝任何的套件,可以自行把 icon 的部分換成你需要的效果。

把腳本放在 Django 的 static_file 資料夾裡,如果不清楚 static_file 資料夾的話,可以參考 Django 從零開始的新手任務 的建立 static_files 目錄和設定靜態檔案路徑

djangoSimpleCaptcha.js

document.addEventListener('DOMContentLoaded', () => {
  // 驗證碼圖片
  const captchaImage = document.querySelector('img.captcha')
  // 重新整理 icon
  const icon = document.createElement('i')
  // 重新整理按鈕
  const refreshButton = document.createElement('a')
  // 是否在請求中
  let isFetching = false

  icon.classList.add('bi', 'bi-arrow-clockwise')
  refreshButton.href = 'JavaScript:void(0);'
  refreshButton.classList.add('captcha-refresh')
  refreshButton.appendChild(icon)
  captchaImage.parentNode.insertBefore(refreshButton, captchaImage.nextSibling)

  // 監聽重新整理點擊
  refreshButton.addEventListener('click', (event) => {
    event.preventDefault()

    /**
     * @type {Element|null} 表單
     */
    const form = event.target.closest('form')
    const url = `${location.origin}/captcha/refresh/`

    if (isFetching) {
      return
    }
    isFetching = true

    fetch(url, {
      headers: {
        'X-Requested-With': 'XMLHttpRequest'
      }
    })
      .then((response) => response.json())
      .then((json) => {
        const input = form.querySelector('input[name="captcha_0"]')
        input.value = json.key
        captchaImage.src = json.image_url
      })
      .catch((error) => {
        console.log(error)
      })
      .finally(() => {
        isFetching = false
      })
  })
})

接下來把 djangoSimpleCaptcha.js 放在 template 模板裡即可,如下

<script src="{% static 'djangoSimpleCaptcha.js' %}"></script>
觀看次數: 1369
captchadjangopython
按讚追蹤 Enjoy 軟體 Facebook 粉絲專頁
每週分享資訊技術

一杯咖啡的力量,勝過千言萬語的感謝。

支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!