• 1.2博客系统 |登录页| 验证码


    基于用户认证组件和Ajax实现登录验证

    UserInfo表既有原生auth_user表的字段,又有你扩展的字段,以后用的接口UserInfo既是自己的用户表又是原生认证组件的用户表

    1.登录页面的设计

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="/static/blog/bootstrap/css/bootstrap.css">
    {#    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css">#}
    </head>
    <body>
    <h3>登录页面</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-lg-offset-3">
                <form>
                    {% csrf_token %}
                    <div class="form-group">
                        <label for="user">用户名</label>
                        <input type="text" id="user" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="pwd">密码</label>
                        <input type="password" id="pwd" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="pwd">验证码</label>
                        <div class="row">
                            <div class="col-md-6">
                                <input type="text" class="form-control" id="valid_code">
                            </div>
                            <div class="col-md-6">
                                <img width="270" height="40" id = "valid_code_img" src="/get_validCode_img/" alt="">
                            </div>                                                 ##src 可以加静态文件,也可以动态,       
                        </div>
                    </div>
    
                    <input type="button" class="btn btn-default login_btn pull-right" value="submit"><span class="error"></span>
                </form>
            </div>
        </div>
    </div>

    2.验证码图片的生成

    validCode.py

    import random
    def get_validCode_img(request):
        def get_random_color():  #随机生成一个新的图片背景 
            return (random.randint(0,255), random.randint(0,255), random.randint(0,255))
        #方式一 --> 只需要了解它的流程
        # with open("luffy.jpg",'rb')as f:
        #     data = f.read()    
        #return Httpresponse(data)
      #方式二: pip install pillow --> 图像处理的模块 # from PIL import Image # img = Image.new("RGB",(270,40), color=get_random_color()) #长度270,高度40,color是动态生成的,颜色三要素color=(0,255,0) # with open("validCode.png", "wb")as f: #先加到磁盘上 # img.save(f,'png') #会生成一个叫validCode.png的图片 # with open("validCode.png", "rb")as f: #再读出来;磁盘的处理速度是很慢的 # data = f.read() #方式三: 磁盘内存管理 # from PIL import Image # from io import BytesIO #--->BytesIO就是内存管理 # img = Image.new("RGB",(270,40), color=get_random_color()) # f = BytesIO() #这种方式是放在内存中,f就是内存句柄 # img.save(f,"png") #save到内存里边了 # data = f.getvalue() #取出来 #方式四: from PIL import Image, ImageDraw, ImageFont #ImageDraw是画笔, ImageFont是字体大小 from io import BytesIO import random img = Image.new("RGB",(270,40), color=get_random_color()) #这是刚刚生成的画板 draw = ImageDraw.Draw(img) #画笔draw只为画板img服务。 draw.text()写文字 、draw.line()画线 、draw.point()画点 kumo_font = ImageFont.truetype("static/font/kumo.ttf", size=32) #参数为字体路径、大小;ttf字体 ;拿到关于kumo.ttf的字体对象
      for i in range(5):
            random_num = str(random.randint(0,9))
            random_low_alpha = chr(random.randint(95,122)) #随机小写字母
            random_upper_alpha = chr(random.randint(65,90)) #随机大写字母
            random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])
            draw.text((i*50+20, 5), random_char, get_random_color(), font=kumo_font)
      f = BytesIO()
        img.save(f,"png")
        data = f.getvalue()

    噪声噪线

    validCode.py

       width = 270  #要跟上边的宽高一致
        height = 40
        for i in range(10):
            x1 = random.randint(0,width)
            x2 = random.randint(0,width)
            y1 = random.randint(0,height)
            y2 = random.randint(0,height)
            draw.line((x1,y1,x2,y2), fill = get_random_color())
        for i in range(100):
            draw.point([random.randint(0,width), random.randint(0,width), random.randint(0,height), random.randint(0,height)])
            x = random.randint(0,width)
            y = random.randint(0,height)
            draw.arc((x, y, x+4, y+4),0, 90, fill=get_random_color())

    3.验证码刷新

     $("#valid_code_img")[0]
    <img width=​"270" height=​"40" id=​"valid_code_img" src=​"http:​/​/​127.0.0.1:​8000/​get_validCode_img/​??" alt>​
     $("#valid_code_img")[0].src
    "http://127.0.0.1:8000/get_validCode_img/??"
    
     $("#valid_code_img")[0].src+="?"  #+="?"添加一次这个就刷新一次验证码
    "http://127.0.0.1:8000/get_validCode_img/???"
     $("#valid_code_img")[0].src+="?"
    "http://127.0.0.1:8000/get_validCode_img/????"
     $("#valid_code_img")[0].src+="?"
    "http://127.0.0.1:8000/get_validCode_img/?????"
     $("#valid_code_img")[0].src+="?"
    "http://127.0.0.1:8000/get_validCode_img/??????"
     $("#valid_code_img")[0].src+="?"
    "http://127.0.0.1:8000/get_validCode_img/???????"

    login.html

    <script src="/static/js/jquery-3.2.1.min.js"></script>
    <script>
        //刷新验证码,不用ajax也可以
        $("#valid_code_img").click(function(){
            $(this)[0].src += "?"
        });

    4.保存验证码字符串

    validCode.py

    valid_code_str = "" #保存验证码字符串,这样才能验证
        for i in range(5):
            random_num = str(random.randint(0,9))
            random_low_alpha = chr(random.randint(95,122))
            random_upper_alpha = chr(random.randint(65,90))
            random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])
            draw.text((i*50+20, 5), random_char, get_random_color(), font=kumo_font)
    
            #保存验证码字符串
            valid_code_str += random_char #做一个累加
    
        print("valid_code_str", valid_code_str)
        request.session["valid_code_str"] = valid_code_str  #保存它,写一个session
    
        '''
        1 sdajsdq33asdf #生成一个随机字符串,
        2 COOKIE {"sessionid":sdajsdq33asdf} #设置一个cookie,返回给cookie那边一个键叫sessionid,值是随机字符串
        3 django-session   #数据部分保存到了django_session;在session表进行存储
          session-key   session-data
          sdajsdq33asdf  {"valid_code_str":"12345"}
        '''
    
        f = BytesIO()
        img.save(f,"png")
        data = f.getvalue()
    
        return HttpResponse(data)

    5.登录验证

    #global valid_code_str 这里不能把它变成全局变量,这时虽然校验时可以拿到valid_code_str,但如果是两个人一块访问,
    那么那个验证码的值存的是最后一个人访问(刷新)的,前面那个人那个就取不到了

    应该每个人的单独保存,使用会话跟踪技术,把每个人校验的值存到cookie里边
    views.py
    from django.shortcuts import render, HttpResponse, redirect
    from django.http import JsonResponse
    from django.contrib import auth
    # Create your views here.
    def login(request):
        if request.method == "POST":
            response = {"user":None, "msg":None} #先构建一个字典,"user":None默认没有登录成功,"msg"里边放错误信息
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            valid_code = request.POST.get("valid_code")
            valid_code_str = request.session.get("valid_code_str")
            if valid_code.upper() == valid_code_str.upper(): #不区分大小写
                user = auth.authenticate(username=user, password=pwd) #用户认证组件
                if user:      #把这个user注册进去,只要登录成功了request.user就是当前登录对象用户,否则它就是个匿名对象。
                    auth.login(request,user) #request.user == 当初登录对象 #登录成功了 #登录成功,在这里不能跳转,用的是ajax请求并不是form请求,ajax请求只接收一个数据data
                    response["user"] = user.username  #user返回值
                else: 
                    response["msg"] = "username or password error!"
            else: #验证码校验失败,成功了就是null
                response["msg"] = "valid code error"
            return JsonResponse(response) #直接把字典放里边,它帮我们序列化,而且在ajax那边直接拿到对象也不用反序列化。
        return render(request,"login.html")
    
    def index(request):
        return render(request,"index.html")

     login.html

       //登录验证
        $(".login_btn").click(function(){
            $.ajax({
                url:"",
                type:"post",
                data:{
                    user:$("#user").val(), #用户名的校验
                    pwd:$("#pwd").val(),  #密码的校验
                    valid_code:$("#valid_code").val(), #验证码的校验
                    csrfmiddlewaretoken:$("[name = 'csrfmiddlewaretoken']").val(), #form请求的csrf校验
                },  #把这4个值传了
                success: function (data) {
                    console.log(data);
                    if(data.user){    //判断有没有值,出错就把错误信息显示到页面上
                        location.href="/index/" //登录成功就跳转到index页面
                    }
                    else{
                        $(".error").text(data.msg).css({"color":"red", "margin-left":'10px'})  //拿到error这个标签;可以加css
                    }
                }
            })
        })
    </script>
    
    </body>
    </html>

    创建超级用户

    C:UsersAdministratorPycharmProjectsDjangocnblog>python manage.py createsuperuser
    Username: kris
    Email address:
    Password:
    Password (again):
    Superuser created successfully.

    index.html(返回的一个页面)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>{{  request.user.username}}</h3>
    </body>
    </html>

     6.总结:

       一次请求伴随多次请求;  PIL;  session存储;  验证码刷新;

     附:

    滑动验证码--->引入这样一个插件

    要先把social-auth-app-django下载下来

    C:UsersAdministrator>pip install social-auth-app-django
    Collecting social-auth-app-django

    把它嵌入到我们的代码里边

  • 相关阅读:
    airtest支持Cocos-Creator,SDK接入
    Python的getter和setter方法
    liunx常用命令
    liunx的vim常用命令收集
    django+atx+liunx的一些shell脚本
    django+airtest+atx部署liunx平台
    Android下的鉴权实现方案
    Mate20 pro实现H265 (HEVC)实时硬件编码
    OpenCV C++常用功能介绍
    Ubuntu16.04编译libjpeg-turbo库
  • 原文地址:https://www.cnblogs.com/shengyang17/p/9227237.html
Copyright © 2020-2023  润新知