zoukankan      html  css  js  c++  java
  • django验证码功能

    1.目的  

       现在我们一般访问网页都需要输入验证码,比如博客园,有的甚至是通过手机验证码实时登录。这样做的目的主要还是为了防止其他人的恶意访问,比如爬虫,下面就来看看验证码是如何实现的

    2.StringIO和BytesIO

      这两者都是给内存中读写文件使用的

      StringIO主要是以字符串的形式在内存中进行读写操作

      BytesIO主要是以二进制的形式在内存中进行读写操作

    2.1StringIO

    from io import StringIO
    
    f = StringIO()
    f.write('luffy')
    f.write('')
    f.write('你好')
    print(f.getvalue())  # getvalue,用于获得写入后的str

    效果:

    2.2BytesIO

    from io import BytesIO
    
    f = BytesIO()
    f.write('luffy'.encode("utf-8"))
    f.write('/t'.encode("utf-8"))  # 很奇葩的是这里转移符也必须进行编码,否则报错
    f.write('你好'.encode("utf-8"))
    print(f.getvalue())  # getvalue,用于获得写入后的str

    效果:

    # 该案例说明转移符也需要进行转换,它也能够转成bytes类型

    3.演示

      这里我在项目下创建了一个utils文件,存放验证码文件,字体文件下载猛戳这里

    utils/code.py

    import random
    from PIL import Image,ImageDraw,ImageFont,ImageFilter
    def check_code(width=120, height=30, char_length=5, font_file='kumo.ttf', font_size=28):
        """
        生成一个120*30验证码框体,28字体,字体文件需自己导入
        char_length代表生成5个字母
        :return:
        """
        code = []   # 用于存放每个验证码
        img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
        draw = ImageDraw.Draw(img, mode='RGB')
    
        def rndChar():
            """
            生成随机字母A-Z
            :return:
            """
            return chr(random.randint(65, 90))
    
        def rndColor():
            """
            生成随机颜色
            :return:
            """
            return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))
    
        # 写文字
        font = ImageFont.truetype(font_file, font_size)
        for i in range(char_length):
            char = rndChar()
            code.append(char)   # 循环了char_length次并追加进去
            h = random.randint(0, 4)
            draw.text([i * width / char_length, h], char, font=font, fill=rndColor())
    
        # 写干扰点
        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 = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
        return img, ''.join(code)
    View Code

    views.py

    from django.shortcuts import render,HttpResponse,redirect
    from django.contrib import auth
    # 从utils文件夹下的code文件导入 check_code
    from utils.code import check_code
    
    def code(request):
        """
        生成图片验证码
        """
        img,random_code = check_code()
        request.session['random_code'] = random_code
        from io import BytesIO
        # 实现了在内存中操作bytes
        stream = BytesIO()
        # 将二维码最终转为png格式
        img.save(stream, 'png')
        return HttpResponse(stream.getvalue())
    
    def login(request):
        """
        用户登陆
        """
        if request.method == 'GET':
            return render(request,'login.html')
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        code = request.POST.get('code')
        if code.upper() != request.session['random_code'].upper():
            return render(request,'login.html',{'msg':'验证码错误'})
        # 通过auth模块进行用户认证
        user = auth.authenticate(username=user,password=pwd)
        if user:
            return redirect('https://www.luffycity.com')
        return render(request, 'login.html', {'msg': '用户名或密码错误'})
    View Code

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form method="post">
            {% csrf_token %}
            <p>
                <input type="text" name="user" placeholder="用户名" />
            </p>
            <p>
                <input type="password" name="pwd" placeholder="密码" />
            </p>
            <p>
                <input type="text" name="code" placeholder="验证" />
                <img onclick="changeImg(this);" src="/code/" alt="" title="点击更换">
            </p>
            <input type="submit" value="提交">{{ msg }}
        </form>
        <script>
            // 通过changeImg事件来更换图片
            function changeImg(ths) {
                ths.src = ths.src + '?';
                console.log(ths.src);
            }
        </script>
    </body>
    </html>
    View Code

    #  这里每次点击图片,图片就会刷新,这是给url通过get的方式传参数实现改变图片验证码的,通过给/code/添加了一个js实现的

    # 至于每次发送get请求为什么后面追加问号,按照我个人理解应该是语法规定,尝试其他字符均会报错

    # 对于这里是如何利用random模块实现验证码功能的,详细内容可以参考这里

  • 相关阅读:
    iOS_03_为什么选择ios开发
    iOS_02_什么是ios开发
    iOS_01_什么是ios
    Hadoop之HDFS
    hadoop组件及其作用
    数组
    Scala基础知识(二)
    hadoop安装过程
    Scala基础知识
    建造者模式
  • 原文地址:https://www.cnblogs.com/LearningOnline/p/9346270.html
Copyright © 2011-2022 走看看