zoukankan      html  css  js  c++  java
  • 如何使用Django实现用户登录验证

      最初开始搞用户登录验证的时候感觉没什么难的,不就是增删改查中的查询数据库么,但是还是遇到许多小问题,而且感觉在查询数据库的时候,要把前端的数据一条一条的进行比对,会导致我的代码很丑,而且方式很不智,所以进行了一些优化。

      除此之外,我还加入了验证码的功能,同时使用form表单验证,功能应该是大致完善了。

    check_code.py:

    #!/usr/bin/python
    
    from PIL import Image,ImageDraw,ImageFont,ImageFilter
    import random
    import string
    
    ttf='C:WindowsFonts'
    
    def getCheckChar():
        ran=string.ascii_letters+string.digits  #ascii_letters 生成随机字母(大小写),digits生成数字
        check_char=''
        for i in range(4):
            check_char+=random.choice(ran)
        print(check_char)
        return check_char
    
    def getImg(code):
        img=Image.new('RGB',(120,30),(255,255,255))
        draw=ImageDraw.Draw(img)
        font = ImageFont.truetype('C:WindowsFontsMonaco.ttf', 18)
        code=code
        color=random.randint(50, 150), random.randint(50, 150), random.randint(50, 150)
        for t in range(4):
            draw.text((28*t,0),code[t],color,font)
        # draw.text((60,0),code,color,font)
        #干扰点
        chance=min(100, max(0, int(2)))
        for w in range(120):
            for h in range(30):
                tmp = random.randint(0, 100)
                if tmp > 100 - chance:
                    draw.point((w, h), fill=(0, 0, 0))
        #干扰线
        for i in range(3):
            # 起始点
            begin = (random.randint(0, 120), random.randint(0, 30))
            # 结束点
            end = (random.randint(0, 120), random.randint(0, 30))
            draw.line([begin, end], fill=(0, 0, 0))
        #图形扭曲参数
        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((120,30), Image.PERSPECTIVE,params, Image.BILINEAR)
        img=img.filter(ImageFilter.EDGE_ENHANCE_MORE)
        # img.save(''.join(code)+'.jpg','jpeg')
        return img
    
    if __name__ == '__main__':
        code=getCheckChar()
        getImg(code)
    View Code

    这个py文件我单独的写出来了,和views.py在同一目录下,作用是生成验证码,包括字符串和图片,要import的模块是pillow,对应的PIL

    tty是字体文件,我用的是   Monaco.ttf ,自己下载的,注意要对应好它所在的位置

    保存的话,如果你想单独用保存可以使用save方法保存,在views里我直接将图片保存在了内存里。

    其他的都是pillow的正常操作了,什么大小啦滤镜啦,不赘述了。

    views.py:

    from django.shortcuts import render,HttpResponse,redirect
    from EMsystem import models
    from EMsystem import check_code
    from io import BytesIO
    
    def getcheck_code(request):
        code = check_code.getCheckChar()
        img = check_code.getImg(code)
        f = BytesIO()
        img.save(f, 'PNG')
        request.session['check_code']=code
        return HttpResponse(f.getvalue())
    
    from django import forms
    from django.forms import fields  #上传文件用
    class FM(forms.Form):       #这里要接受后端需要的,不需要的数据不会关注
        teacher_id=forms.CharField(error_messages={'required':"不能为空"})  #表单中的name要与变量名一样
        password=forms.CharField(
            min_length=5,
            error_messages={'required':"不能为空",
                            'min_length':'密码长度不小于5',},
        )
    
    def login_page(request):
        if request.method=="GET":
            return render(request,'login.html')
        if request.method=='POST':
            obj=FM(request.POST)
            if obj.is_valid():
                print(obj.cleaned_data)
                check_dic=models.teacher_list.objects.filter(**obj.cleaned_data).first()
                if check_dic is None:
                    return render(request,'login.html')
                else:
                    checkcode=request.POST.get('checkcode')
                    if checkcode.upper()==request.session['check_code'].upper():
                        request.session['userid']=obj.cleaned_data['teacher_id']
                        request.session['is_login']=True
                        return render(request,'welcome.html')
                    else:
                        return render(request, 'login.html', {'err_checkcode': "验证码错误"})
            else:
                return render(request,'login.html',{'obj':obj})
    
    def welcome(request):
        if request.session.get('is_login',None):
            return render(request,'welcome.html')
        else:
            return redirect('/login/')

    视图函数里写了四个函数:

      getcheck_code:作用是生成验证码,同时保存到session中,图片保存到内存里并以HttpResponse提交到前端。

      FM:作用是表单验证,这是django自带的form操作,用于检验前端的数据格式是否正确(前面的博文有介绍)。

      login_page:作用是验证数据库和session中的验证码,这里直接使用了form的两个方法:

        is_valid:检验字段是否正确
        cleaned_data:将正确的结果以字典的形式返回

        拿到cleaned_data之后直接怼到数据库里面filter一下,看是否为空,如果为空说明用户名密码不匹配,否则验证成功

    check_dic=models.teacher_list.objects.filter(**obj.cleaned_data).first()

       注意如果遇到session报 " KeyError "的问题就在terminal里执行以下两条命令,然后重启服务就可以了:

    python manage.py makemigrations
    
    python manage.py migrate

      welcome:验证通过后访问的主页,如果直接访问该页面的话,会先检查is_login这个session是否为True(有关session的使用方法在前面的博文里)

    验证成功之后返回welcome.html

    HTML:

    login.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="login.html" method="POST">
            {% csrf_token %}
            <p>username: <input type="text" name="teacher_id">{{ obj.errors.userid.0}}</p>
            <p>password:<input type="password" name="password">{{ obj.errors.password.0 }}<p>
            <p>
                验证码:  <input type="text" name="checkcode">{{ err_checkcode }}
                <span>
                    <img src="/checkcode.html" onclick="chageCheckcode(this)">
                </span>
            </p>
            <input type="submit" value="login">
    
        </form>
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function chageCheckcode(ths) {
                console.log(ths.src)
                ths.src=ths.src+'?'
            }
        </script>
    </body>
    </html>
    View Code

    urls.py:

    urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^welcome/',views.welcome),
    url(r'^login/',views.login_page),
    url(r'^checkcode.html$',views.getcheck_code),
    ]

    这样就实现了登录认证功能

  • 相关阅读:
    Linux操作系统是如何工作的?破解操作系统的奥秘
    SSIS Send Mail
    数据库邮件
    Script component 用法
    OleDB Destination 用法
    OLE DB Command transformation 用法
    Conditional Split component 用法
    Execute Sql Task 的Result DataSet如何返回
    binary 和 varbinary 用法全解
    TSQL HASHBYTES 用法
  • 原文地址:https://www.cnblogs.com/SunsetSunrise/p/7828397.html
Copyright © 2011-2022 走看看