一、驗(yàn)證碼的作用
防惡意破解密碼:防止,使用程序或機(jī)器人惡意去試密碼.為了提高用戶的體驗(yàn),用戶輸入錯(cuò)誤以后,才會(huì)要求輸入驗(yàn)證碼.
防論壇灌水:這個(gè)是很常見的。有一種程序叫做頂帖機(jī),如果無(wú)限制的刷,整個(gè)論壇可能到處是拉圾信息,比如,百度貼吧,你只要是新用戶或者剛剛關(guān)注的貼吧,要是發(fā)帖,會(huì)馬上出現(xiàn)驗(yàn)證碼。
有效防止注冊(cè):防止使用程序或機(jī)器人去無(wú)限制注冊(cè)賬號(hào).
防刷票:網(wǎng)上有很多投票類的網(wǎng)站.
反爬:防止爬蟲爬取數(shù)據(jù)
二、原理
驗(yàn)證碼于服務(wù)器端生成,發(fā)送給客戶端,并以圖像格式顯示??蛻舳颂峤凰@示的驗(yàn)證碼,客戶端接收并進(jìn)行比較,若比對(duì)失敗則不能實(shí)現(xiàn)登錄或注冊(cè),反之成功后跳轉(zhuǎn)相應(yīng)界面。
流程
?
三、如何實(shí)現(xiàn)
1、前期配置
- 安裝pillow
pip install Pillow - 安裝django-simple-captcha
pip install django-simple-captcha==0.5.6 - 將captcha添加到setting的app中
INSTALLED_APPS = [ 'captcha', ] - 添加urls.py
urlpatterns += [ url(r'^captcha/', include('captcha.urls')), ] - 配置
# django_simple_captcha 驗(yàn)證碼配置 # 格式 CAPTCHA_OUTPUT_FORMAT = u'%(text_field)s %(hidden_field)s %(image)s' # 噪點(diǎn)樣式 CAPTCHA_NOISE_FUNCTIONS = ('captcha.helpers.noise_null', # 沒有樣式 # 'captcha.helpers.noise_arcs', # 線 # 'captcha.helpers.noise_dots', # 點(diǎn) ) # 圖片大小 CAPTCHA_IMAGE_SIZE = (100, 25) CAPTCHA_BACKGROUND_COLOR = '#ffffff' CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge' # 圖片中的文字為隨機(jī)英文字母,如 mdsh # CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge' # 圖片中的文字為數(shù)字表達(dá)式,如1+2=</span> CAPTCHA_LENGTH = 4 # 字符個(gè)數(shù) CAPTCHA_TIMEOUT = 1 # 超時(shí)(minutes)
2、示例代碼
- forms.py
from django import forms from maiziedu.models import UserProfile from captcha.fields import CaptchaField class RegisterForm(forms.Form): ''' 注冊(cè) ''' username = forms.EmailField(widget=forms.TextInput(attrs={"placeholder": "請(qǐng)輸入郵箱賬號(hào)", "value": "", "required": "用戶名不能為空",}),max_length=50,error_messages={"required": "用戶名不能為空",}) password = forms.CharField(widget=forms.PasswordInput(attrs={"placeholder": "請(qǐng)輸入密碼", "value": "", "required": "密碼不能為空",}),min_length=8, max_length=50,error_messages={"required": "密碼不能為空",}) # 驗(yàn)證碼 captcha = CaptchaField() def clean(self): # 驗(yàn)證碼 try: captcha_x = self.cleaned_data['captcha'] except Exception as e: raise forms.ValidationError(u"驗(yàn)證碼有誤,請(qǐng)重新輸入") # 用戶名 try: username=self.cleaned_data['username'] except Exception as e: raise forms.ValidationError(u"注冊(cè)賬號(hào)需為郵箱格式") # 登錄驗(yàn)證 is_email_exist = UserProfile.objects.filter(email=username).exists() is_username_exist = UserProfile.objects.filter(username=username).exists() if is_username_exist or is_email_exist: raise forms.ValidationError(u"該賬號(hào)已被注冊(cè)") # 密碼 try: password=self.cleaned_data['password'] except Exception as e: raise forms.ValidationError(u"請(qǐng)輸入至少8位密碼"); return self.cleaned_data - 刷新驗(yàn)證碼
# 刷新驗(yàn)證碼 def refresh_captcha(request): verify= dict() verify['cptch_key'] = CaptchaStore.generate_key() verify['cptch_image'] = verify(to_json_response['cptch_key']) return HttpResponse(json.dumps(verify), content_type='application/json') - views.py
def register(request): if request.method == 'POST': # 驗(yàn)證碼 try: reg_form = RegisterForm(request.POST) except Exception as e: # 登錄失敗 返回錯(cuò)誤提示 err = "注冊(cè)失敗,請(qǐng)重試" return result_response(request, err) if reg_form.is_valid(): try: username = reg_form.cleaned_data['username'] password = reg_form.cleaned_data['password'] user = UserProfile.objects.create(username = username, email = username, password = make_password(password), is_active = True) user.save() # 驗(yàn)證成功登錄 auth.login(request, user) return result_response(request, "") except Exception as e: setFormTips(reg_form, "注冊(cè)失敗,請(qǐng)重試") else: if request.POST.get('captcha_1') == "": setFormTips(reg_form, "驗(yàn)證碼不能為空") # 登錄失敗 返回錯(cuò)誤提示 err = getFormTips(reg_form) return result_response(request, err) else: reg_form = RegisterForm() # locals() 傳遞所有變量 return render(request, 'index.html', locals()) - 刷新驗(yàn)證碼
?$(function () { let refres_url = 'http://127.0.0.1:8000/account/verify/'; $('.captcha').click(function () { $.getJSON(refres_url, function (data) { $('.captcha').attr('src', data.img_url) $('#id_capt_0').val(data.haskey) }) }) })