Django 创建随机验证码

版权声明:转载请注明出处 https://blog.csdn.net/GG9527li/article/details/86701905

Django上实现登录验证码有两种方式(我自己能实现的)

第一种调用captcha 验证码插件
安装:pycharm 中直接搜索django-simple-captcha,或者pip3 install django-simple-captcha
安装后在settings.py 中引入captcha

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'captcha',
]

然后在url.py中配置

url(r'^captcha/', include('captcha.urls'))

然后在pycharm 中用快捷键ctrl + alt + R 或者Tools>Run manage Task 后 在下方输入makemigrations ,migrate
然后登陆页面效果如下:在这里插入图片描述
然后在后台写个form 表单 对前端输入的验证码是否正确做判断

from django import forms
from captcha.fields import CaptchaField

class RegisterForm(forms.Form):
    email = forms.EmailField(required=True)
    password = forms.CharField(required=True,min_length=5)
    captcha = CaptchaField(error_messages={"invalid":"验证码错误"})  #加入这条

然后再前端加上验证码的引用

<div class="form-group marb8 captcha1 {% if register_form.errors.captcha %} errorput {% endif %} ">
        <label>验&nbsp;证&nbsp;码</label>{{ register_form.captcha }}  
  </div>

验证码图片是captcha随机生成的
第二种方法是通过PIL 随机拼接生成
活不多说直接上代码

from PIL import Image,ImageDraw,ImageFont,ImageFilter
import random
import math, string

#字体的位置,不同版本的系统会有不同
font_path = '/Library/Fonts/Arial.ttf'
#font_path = '/Library/Fonts/Hanzipen.ttc'
#生成几位数的验证码
number = 4
#生成验证码图片的高度和宽度
size = (100,30)
#背景颜色,默认为白色
bgcolor = (255,255,255)
#字体颜色,默认为蓝色
fontcolor = (0,0,255)
#干扰线颜色。默认为红色
linecolor = (255,0,0)
#是否要加入干扰线
draw_line = True
#加入干扰线条数的上下限
line_number = (1,5)
def gen_text():
    source = list(string.ascii_letters)
    for index in range(0,10):
        source.append(str(index))
    return ''.join(random.sample(source,number))#number是生成验证码的位数

#用来绘制干扰线
def gene_line(draw,width,height):
    begin = (random.randint(0, width), random.randint(0, height))
    end = (random.randint(0, width), random.randint(0, height))
    draw.line([begin, end], fill = linecolor)

def gene_code(save_path,filename):
    width,height = size #宽和高
    image = Image.new('RGBA',(width,height),bgcolor) #创建图片

    font = ImageFont.truetype(font_path,25) #验证码的字体和字体大小
    #font = ImageFont.truetype(25) #验证码的字体和字体大小
    draw = ImageDraw.Draw(image) #创建画笔
    #text = "我是中国人" #生成字符串
    text = gen_text() #生成字符串
    print(text)
    font_width, font_height = font.getsize(text)
    draw.text(((width - font_width) / number, (height - font_height) / number),text,\
        font= font,fill=fontcolor) #填充字符串
    if draw_line:
        gene_line(draw, width, height)
        gene_line(draw, width, height)
        gene_line(draw, width, height)
        gene_line(draw, width, height)
    image = image.transform((width + 20, height +10), Image.AFFINE, (1, -0.3, 0, -0.1, 1, 0), Image.BILINEAR)  # 创建扭曲
    image = image.filter(ImageFilter.EDGE_ENHANCE_MORE)  # 滤镜,边界加强
    image.save('%s/%s.png' %(save_path,filename))  # 保存验证码图片
    print("savepath:",save_path)
    return text
if __name__ == "__main__":
    gene_code('/picture','test')        #会把生成的图片保存到/picture/test.png

在前端使用Django 自带的post请求将填写的验证码发送到后端(不知道Django原生post请求的请百度)
只需在前端加上这段代码

<div class="form-group">
            <div class="input-group">
                    <div class="input-group-addon">
                             <img height="30px" src="/static/verify_code_imgs/{{ today_str }}/{{ filename }}.png">
                      </div>
                         <input style="height: 50px" type="text" name="verify_code" class="form-control" placeholder="验证码">
                         <input  type="hidden" name="verify_code_key" value="{{ filename }}" >
                </div>
  </div>

PS:你必须在生成验证码的同时,把验证码存下来,存到哪? 必然是缓存,这样直接在存的同时加个超时时间 , 就可以限定验证码有效期了。
接下来就是在login中加入判断

def acc_login(request):
    err_msg = {}
    today_str = datetime.date.today().strftime("%Y%m%d")
    verify_code_img_path = "%s/%s" %(settings.VERIFICATION_CODE_IMGS_DIR,
                                     today_str)
    if not os.path.isdir(verify_code_img_path):
        os.makedirs(verify_code_img_path,exist_ok=True)
    print("session:",request.session.session_key)
    #print("session:",request.META.items())
    random_filename = "".join(random.sample(string.ascii_lowercase,4))
    random_code = verify_code.gene_code(verify_code_img_path,random_filename)
    cache.set(random_filename, random_code,30)

    if request.method == "POST":

        username = request.POST.get('username')
        password = request.POST.get('password')
        _verify_code = request.POST.get('verify_code')
        _verify_code_key  = request.POST.get('verify_code_key')

        print("verify_code_key:",_verify_code_key)
        print("verify_code:",_verify_code)
        if cache.get(_verify_code_key) == _verify_code:
            print("code verification pass!")

            user = authenticate(username=username,password=password)
            if user is not None:
                login(request,user)
                request.session.set_expiry(60*60)
                return HttpResponseRedirect(request.GET.get("next") if request.GET.get("next") else "/")

            else:
                err_msg["error"] = 'Wrong username or password!'

        else:
            err_msg['error'] = "验证码错误!"

    return render(request,'login.html',{"filename":random_filename, "today_str":today_str, "error":err_msg})

PIL产生验证码图片出自以下博客的教学

https://www.cnblogs.com/alex3714/articles/6662365.html

猜你喜欢

转载自blog.csdn.net/GG9527li/article/details/86701905
今日推荐