Django框架实现用户登录验证码 图片验证码+ Session

鳄鱼君

发表文章数:643

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » Django框架实现用户登录验证码 图片验证码+ Session

现在基本的网站登录都有验证码,那么在django中实现也可以实现登录验证码。需要知道具体的原理,首先用户访问login页面,我们在服务器创建一个白板图片并添加随机字符串验证码返回给用户,Session存在随机字符串;用户发送post数据提交的时候,核对用户输入的随机字符串是否跟Session中的一致

首先考虑,生成的图片放在哪。如果放在文件中,需要知道图片的路径才能在页面上显示,也可以放在内存中。很显然不能存在文件中,因为图片验证码是动态生成的,所以放在文件中不合适。

难点就是验证码的生成,这里我们创建一个check_code.py文件来编写验证码图片的代码,主要用的就是pil模块,内容也不多,注释为了更加直观,我就直接写在了后面:

from PIL import Image,ImageDraw,ImageFont,ImageFilter
import random
_letter_cases="abcdefghjkmnpqrstuvwxyz" #小写字母 取出干扰字母i,l,o
_upper_cases=_letter_cases.upper() #大写字母
_numbers=''.join(map(str,range(3,10)))  #数字
init_chars=''.join( (_letter_cases,_upper_cases,_numbers) )
def create_validate_code(
        size=(120,30),      #图片的大小,格式(宽,高),默认为(120,30)
        chars=init_chars,   #允许的字符集合
        img_type='GIF',     #图片保存的格式,默认为为GIF,可选GIF,JPEG,JPG,PNG
        mode='RGB',         #图片格式,默认为RGB
        bg_color=(255,255,255), #背景颜色,默认为白色
        fg_color=(0,0,255), #前景色,验证码字符串颜色,默认为蓝色#0000FF
        font_size=18,       #验证码字体大小
        font_type='JIANTI.ttf',  #验证码字体
        length=4,           #验证码字符格式
        draw_lines=True,   #是否画干扰线
        n_line=(1,2),      #干扰线的条数范围,格式元组,默认为(1,2),只有draw_lines为True时有效
        draw_polints=True, #是否画面干扰
        polint_chance=2,   #干扰点出现的概率,大小范围[0,100]
):
    width,height=size #宽高
    #创建图形
    img=Image.new(mode,size,bg_color)
    draw=ImageDraw.Draw(img) #创建画笔
    def get_chars():
        #生成给定长度的字符串,返回列表格式
        return random.sample(chars,length)
    def create_lines():
        #绘制干扰线
        line_num=random.randint(*n_line) #干扰线条数
        for i in range(line_num):
            #起始点
            begin=(random.randint(0,size[0]),random.randint(0,size[1]))
            #结束点
            end=(random.randint(0,size[0]),random.randint(0,size[1]))
            draw.line([begin,end],fill=(0,0,0))
    def create_polints():
        #绘制干扰点
        chance=min(100,max(0,int(polint_chance))) #大小限制在[0,100]
        for w in range(width):
            for h in range(height):
                tap=random.randint(0,100)
                if tap>100-chance:
                    draw.point((w,h),fill=(0,0,0))
    def create_strs():
        #绘制验证码字符
        c_chars=get_chars()
        strs='%s'% ' '.join(c_chars) #每个字符前后以空格隔开
        font=ImageFont.truetype(font_type,font_size)
        font_width,font_heigth=font.getsize(strs)
        draw.text( (width-font_width-30,height-font_heigth-10 ),
                   strs,font=font,fill=fg_color)
        return strs
    if draw_lines:create_lines() #先画干扰线
    if draw_polints:create_polints()
    strs=create_strs()
    #图形扭曲参数
    params=[1-float(random.randint(1,2)) /100,
            0,0,0,
            1-float(random.randint(1,10)) /100,
            float(random.randint(1,2)) / 500,
            0.001,
            float(random.randint(1,2)) /500]
    img=img.transform(size,Image.PERSPECTIVE,params) #创建扭曲
    img=img.filter(ImageFilter.EDGE_ENHANCE_MORE) #滤镜,边界加强(阈值更大)
    #img图片对象 验证码字符串
    return img,strs.replace(" ","")

以上代码返回一个验证码图片用于展示在页面中和验证字符串用于核对,验证码图片可以存放在内存中,并且在页面可以刷新验证码:

views视图函数
from check_code import create_validate_code
def login(request):
    if request.method=='GET':
        return render(request,'login.html')
    if request.method=='POST':
        user_strs=request.POST.get('check_code').upper()
        check_code=request.session['CheckCode'].upper()
        if user_strs==check_code:
            return render(request,'index.html')
        else:
            return render(request,'login.html')
from io import BytesIO
def check_code(request):
    # 1.创建一张图片   pip3 install Pillow
    # 2.在图片中写入随机字符串
    # 3.将图片写入到指定文件
    # 4.打开指定目录文件,读取内容
    stream=BytesIO()  #字节的io操作 打开一个文件
    img,code=create_validate_code()
    img.save(stream,'PNG')
    request.session['CheckCode']=code  #写入到session中
    return HttpResponse(stream.getvalue()) #读取内存中的内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录管理</title>
<link href="/static/css/login.css" rel="stylesheet">
</head>
<body>
<div id="login">
    <form action="" method="post">
	<strong class="login-title">用户登录</strong>
	<p><input type="username" name="user" id="user" placeholder="用户名"></p>
	<p><input type="password" name="passw0rd" id="pwd" placeholder="密码"></p>
	<p><input type="text" name="check_code" id="yzm" placeholder="验证码"></p>
        <p><图片标签img src="/check_code.html/" onclick="changeCheck(this);"></p>
	<p><input type="submit" id="submit" value="登录"></p>
    </form>
</div>
<div style="text-align:center;">
</div>
<script>
    function changeCheck(ths) {
        ths.src=ths.src+"?"; //改变图片的url地址,让图片刷新
    }
</script>
</body>
</html>

login.html页面的img标签是后台自动添加的,主要就是src属性和绑定的时间,用户点击的是后更改图片的url地址,让图片验证码可以刷新,具体的效果如图:

Django框架实现用户登录验证码 图片验证码+ Session

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《Django框架实现用户登录验证码 图片验证码+ Session》 发布于2020-04-30

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

3 + 4 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册