Django Simple Captcha 驗證碼
分類
說明
最近 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>
一杯咖啡的力量,勝過千言萬語的感謝。
支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!