• 页面登陆系统--带文字验证码


    页面登陆系统--带文字验证码

    需要模块:

    Pillow        # 图像处理模块
    io            # 可将数据从内存发送到客户端
    random        # 生成随机字符串
    

    通过生成图像验证码实现用户登陆验证

    1.url页面配置

    from django.conf.urls import url
    from django.contrib import admin
    from blog import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^get_valid_img/', views.get_valid_img),
        url(r'^index/', views.index),
    ]
    

    2.视图页面配置

    from django.shortcuts import render,HttpResponse,redirect
    
    # Create your views here.
    from PIL import Image
    from django.contrib import auth
    from .models import *
    import json
    from django.contrib.auth.decorators import login_required
    from io import BytesIO
    from PIL import Image,ImageDraw,ImageFont
    import random, string
    
    
    # 该部分为login 登陆页面
    def login(request):
        if request.is_ajax():   # 判断当次 请求是否 为 ajax 是返回Ture
            # 获取前端传入得 值
            username=request.GET.get("username")
            password=request.GET.get("password")
            valid=request.GET.get("valid")            # 为验证码值
    
            # 获取session 中的值,验证码值
            keep_valid = request.session.get("valid_code")
    
            # 生成字典集
            loginResponse = {"user":None, "error_msg":None}
            # 判断用户输入得验证码 和 session 中获取得是否一样
            if valid.upper() == keep_valid.upper():
                # 直接通过 authenticate 可以直接调用 auth_user 表中的用户进行验证;验证成功,就会有返回值,否则返回None
                user = auth.authenticate(username=username,password=password)
                
                # 匹配给 session 绑定相应的值 user  (固定写法)
                auth.login(request, user)
                if user:
                    # 如果 user 不为空,即代表验证成功
                    loginResponse["user"]=username
                else:
                    loginResponse["error_msg"] = "用户名密码错误"
    
            else:
                loginResponse["error_msg"] = "验证码错误"
                
            # 将该字典序列化传给前端 loginResponse
            return HttpResponse(json.dumps(loginResponse))
        return render(request,"login.html")
        
    
    # 该部分为生成验证码部分
    def get_valid_img(request):
        f = BytesIO()
    
        # 生成随机背景色
        img = Image.new(mode="RGB",
                        size=(120, 30),
                        color=(random.randint(0,255),
                               random.randint(0, 255),
                               random.randint(0, 255),
                                ))
    
        draw = ImageDraw.Draw(img, mode="RGB")
        # 定义字体样式 文件,以及字体大小
        font = ImageFont.truetype("blog/static/dist/fonts/kumo.ttf", 28)
        # 20,0 表示 坐标,字体内容,引用字体样式
    
        # 用于获取 生成的随机字符串
        char_list = []
        for i in range(5):
            # 随机生成 数字string.ascii_letters 大写+小写 + string.digits 数字
            aaa = string.ascii_letters + string.digits
    
            # 随意取出一个字符
            abc = "".join(random.sample(aaa, 1))
            char_list.append(abc)
            draw.text([i * 24, 0],
                      abc,
                      (random.randint(0, 255),
                       random.randint(0, 255),
                       random.randint(0, 255),
                       ),
                      font=font)
        print(char_list)
    
        # 将生成 ['l', 'm', 'y', 'Z', 'T'] 字典形式 转换为 字符串 lmyZT
        s = "".join(char_list)
        print(s)
    
        # 设置一个 session 字段 等于 生成得验证码 s 相应到前端
        request.session["valid_code"] = s
    
        # 干扰部分
        width = 120
        height = 30
    
    # 干扰器部分
        def rndColor():
            """
            生成随机颜色
            :return:
            """
            return (random.randint(0, 255),
                    random.randint(10, 255),
                    random.randint(64, 255))
        # 写干扰点
        for i in range(40):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
    
        # 写干扰圆圈
        for i in range(40):
            draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())
            x = random.randint(0, width)
            y = random.randint(0, height)
            draw.arc((x, y, x + 4, y + 4), 0, 90, fill=rndColor())
    
        # 画干扰线
        for i in range(5):
            x1 = random.randint(0, width)
            y1 = random.randint(0, height)
            x2 = random.randint(0, width)
            y2 = random.randint(0, height)
    
            draw.line((x1, y1, x2, y2), fill=rndColor())
    
        img.save(f, "png")
        data = f.getvalue()
        return HttpResponse(data)
    
    
    # index 页面返回
    @login_required(login_url='/login/')
    def index(request):
        return HttpResponse("index")
    

    3.模板部分login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    
        <link rel="stylesheet" href="/static/css/login.css">
        <link rel="stylesheet" href="/static/dist/css/bootstrap.css">
        <script src="/static/dist/js/jquery-3.2.1.js"></script>
        <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
        <script src="/static/dist/js/bootstrap.js"></script>
    
    </head>
    <body>
    
    <div class="container">
        <div class="row">
            <form class="col-md-6 col-md-offset-3">
                <div class="form-group">
                    <label for="user">用户名</label>
                    <input type="text" class="form-control" id="user" placeholder="user">
                </div>
    
                <div class="form-group">
                    <label for="pwd">密码</label>
                    <input type="password" class="form-control" id="pwd">
                </div>
    
                <div class="row">
                    <div class="form-group col-md-6">
                        <label for="valid">验证码</label>
                        <input type="text" class="form-control" id="valid">
                    </div>
                    <div class="form-group col-md-6">
                        <img class="valid_img" src="/get_valid_img/" width="200px" height="40px">
                    </div>
                </div>
    
                <div class="row">
                    <div class="form-group col-md-6">
                        <input type="button" value="登录" class="btn-primary btn loginbtn">
                        <span class="error"></span>
                    </div>
                    <div class="form-group col-md-6">
                        <a>点击图片刷新</a>
                    </div>
                </div>
            </form>
        </div>
    </div>
    
    <script>
        $(".valid_img").click(function () {
            // 图片标签 http://127.0.0.1:8000/get_valid_img/+? 表示从新请求一次验证码 起到刷新效果
            $(this)[0].src+="?"
        });
    
        // 点击提交时
        $(".loginbtn").click(function () {
            $.ajax({
                url:"/login",
                // 将用户填入输入框数据  通过ajax 发送到 后端
                data:{
                    username:$("#user").val(),
                    password:$("#pwd").val(),
                    valid:$("#valid").val(),
                },
                success:function (data) {
                    // 将接收得数据 反序列化
                    var data=JSON.parse(data);
                    if (data["user"]){
                        // data["user"] 里面有数据表示 验证通过 跳转到 index 页面
                        location.href="/index/"
                    }
                    else {
                        // 将错误数据 输出到 指定得位置
                        $(".error").html(data.error_msg).css("color","red")
                        // 设置 2 秒钟消失提示
                        setTimeout(function () {
                            $(".error").html("")
                        },2000)
                    }
                }
            })
        });
    </script>
    </body>
    </html>
    
  • 相关阅读:
    Spark ML参考博客
    Mysql数据库相关
    git clone server certificate verification failed
    GSM网络扫频结果
    USRP E310启用SSH的X11 Forwarding功能
    Win 7 SVN查看日志时出现There has been a problem contacting the server
    OpenWrt修改MAC地址
    NETGEAR WNDR4300路由器tftp方式 刷机
    ubuntu系统中修改hostname
    USRP中sampling rate和master clock rate的区别
  • 原文地址:https://www.cnblogs.com/baolin2200/p/8023638.html
Copyright © 2020-2023  润新知