Django 登录验证码

url.py:

url(r'^verifycode/$',views.verifycode),
url(r'^verifycodefile/$',views.verifycodefile),
url(r'^verifycodecheck/$',views.verifycodecheck),

 

views.py:

def verifycode(request):
    #引入绘图模块
    from PIL import Image, ImageDraw, ImageFont
    #引入随机函数模块
    import random
    #定义变量,用于画面的背景色、宽、高
    bgcolor = (random.randrange(20, 100), random.randrange(
        20, 100), random.randrange(20, 100))
    width = 100
    height = 50
    #创建画面对象
    im = Image.new('RGB', (width, height), bgcolor)
    #创建画笔对象
    draw = ImageDraw.Draw(im)
    #调用画笔的point()函数绘制噪点
    for i in range(0, 100):
        xy = (random.randrange(0, width), random.randrange(0, height))
        fill = (random.randrange(0, 255), 255, random.randrange(0, 255))
        draw.point(xy, fill=fill)
    #定义验证码的备选值
    str = '1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm'
    #随机选取4个值作为验证码
    rand_str = ''
    for i in range(0, 4):
        rand_str += str[random.randrange(0, len(str))]
    #构造字体对象,按照目录找自己电脑的字体,关于后缀,otf或者TTF
    font = ImageFont.truetype(r'C:\Windows\Fonts\Arial.TTF', 40)
    #构造字体颜色
    fontcolor1 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor2 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor3 = (255, random.randrange(0, 255), random.randrange(0, 255))
    fontcolor4 = (255, random.randrange(0, 255), random.randrange(0, 255))
    #绘制4个字
    draw.text((5, 2), rand_str[0], font=font, fill=fontcolor1)
    draw.text((25, 2), rand_str[1], font=font, fill=fontcolor2)
    draw.text((50, 2), rand_str[2], font=font, fill=fontcolor3)
    draw.text((75, 2), rand_str[3], font=font, fill=fontcolor4)
    #释放画笔
    del draw
    #存入session,用于做进一步验证
    request.session['verify'] = rand_str
    #内存文件操作
    buf = io.BytesIO()
    #将图片保存在内存中,文件类型为png
    im.save(buf, 'png')
    #将内存中的图片数据返回给客户端,MIME类型为图片png
    return HttpResponse(buf.getvalue(), 'img/png')

def verifycodecheck(request):
    code1 = request.POST.get("verifycode").upper()
    code2 = request.session.get("verify").upper()
    if code1 == code2:
        return render(request,"myApp/success.html")
    else:
        request.session["flag"] = False
        return redirect('/sunck/verifycodefile/')

def verifycodefile(request):
    f = request.session.get("flag",True)
    str = ""
    if f == False:
        str = "重新输入"
    request.session.clear()
    return render(request,'myApp/verifycodefile.html',{"flag":str})

 

verifycodefile.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/sunck/verifycodecheck/" method="post">
        {% csrf_token %}
        <input type="text" name="verifycode">
        <img src="/sunck/verifycode/">
        <input type="submit" value="登录">
        <span>{{ flag }}</span>
    </form>
</body>
</html>

success.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>登录成功</h1>
</body>
</html>

 

 

1.视图里的verifycode函数是用来生成验证码的,这个函数应该可以随便拿着用(需要安装Pillow这个库)

2.验证码图片在模板里显示是用img标签(<img src="/sunck/verifycode/">),该路径也就是生成验证码函数对应的url

3.服务端在给前端验证码时把验证码本来的字符串存到session(request.session['verify'] = rand_str),前端传来的字符串(request.POST.get("verifycode")),如果两者相等则验证通过;如果不等,代表验证码输入错误,在验证函数里session存一个标志位,再到获取验证码的函数把这个标志位取出来,传一个错误的提示信息给前端(也就是说redirect不能传参数,只能传一个路径,而render的第三个参数可以传一个参数到前端)

session还是好用啊!

posted @ 2019-12-02 15:34  hoo_o  阅读(359)  评论(0编辑  收藏  举报