毕业设计----Django实现验证码登录

开头

       在登陆时添加一个验证码校验功能,当邮箱激活后,用户输入正确的验证码之后才能登录系统。

1.生成图片

安装pillow模块
       Pillow 是一个常用的图像处理库,它提供了丰富的图像处理功能,包括打开、保存、裁剪、调整大小、旋转、滤镜等操作。

pip install pillow

生成验证码图片,这个代码可以直接拿来用
       需要注意的是,这里需要导入一个字体文件,字体文件可以从电脑获取
路径:C:\Windows\Fonts,然后选择一个就可以,我选择的是楷体,然后把STKAITI.TTF这个文件放在项目的根目录下

from PIL import Image, ImageFilter,ImageDraw,ImageFont
import random

def check_code(width=120, height=30, char_length=5, font_file='STKAITI.TTF', font_size=28):
    code = []
    # 创建了一个新的 RGB 模式的图片对象 img,背景颜色为白色
    img = Image.new(mode='RGB', size=(width, height), color=(255, 255, 255))
    # 使用 ImageDraw 模块的 Draw 函数创建了一个绘图对象 draw,用于在图片上绘制文字和图形。
    draw = ImageDraw.Draw(img, mode='RGB')

    def rndChar():
        """
        生成随机字母
        :return:
        """
        return chr(random.randint(65, 90))

    def rndColor():
        """
        生成随机颜色
        :return:
        """
        return (random.randint(0, 255), random.randint(10, 255), random.randint(64, 255))

    # 使用指定的字体文件和字体大小创建了一个字体对象 font,用于绘制文字
    font = ImageFont.truetype(font_file, font_size)
    for i in range(char_length):
        char = rndChar()
        code.append(char)
        h = random.randint(0, 4)
        draw.text([i * width / char_length, h], char, font=font, fill=rndColor())

    #  draw.point() 在图片上绘制一些干扰点,数量为 40 个
    for i in range(40):
        draw.point([random.randint(0, width), random.randint(0, height)], fill=rndColor())

    # draw.arc() 绘制一些干扰圆圈,数量也为 40 个
    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())

    # draw.line() 绘制五条干扰线,起点和终点的坐标都是随机生成的
    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.filter() 对图片进行边缘增强的滤镜处理,并将处理后的图片对象和验证码字符拼接成一个元组返回
    img = img.filter(ImageFilter.EDGE_ENHANCE_MORE)
    return img, ''.join(code)


if __name__ == '__main__':
    # 1. 直接打开
    # img,code = check_code()
    # img.show()

    # 2. 写入文件
    img,code = check_code()
    with open('code.png','wb') as f:
        img.save(f,format='png')

    # 3. 写入内存(Python3)
    # from io import BytesIO
    # stream = BytesIO()
    # img.save(stream, 'png')
    # stream.getvalue()

    # 4. 写入内存(Python2)
    # import StringIO
    # stream = StringIO.StringIO()
    # img.save(stream, 'png')
    # stream.getvalue()
    pass

效果如下
在这里插入图片描述

2.在视图函数中生成验证码函数

def codevalidate(request):
    # 调用生成验证码图片的函数
    img, code_string = check_code()
    print('验证码:', code_string)
    # 写入内存
    from io import BytesIO
    # 在内存中图片以字节流的形式传输
    stream = BytesIO()
    # 写入到自己的session中,以便后续获取验证码进行校验(每个用户自己的验证码)
    request.session['imagecode'] = code_string
    # 给session设置超时时间
    request.session.set_expiry(60 * 60 * 24 * 7)
    img.save(stream, 'png')
    return HttpResponse(stream.getvalue())

3.修改中间件,允许非登录用户访问图片URL

       因为我设置了中间件,所以修改一下代码,放行路径为/bossApp/codevalidate/的路由

class UserMiddleWare(MiddlewareMixin):
    def process_request(self,request):
        path = request.path_info
        print(path)
        # 0.如果请求路由是登录或注册,继续执行
        if path in ['/bossApp/login/','/bossApp/register/','/bossApp/codevalidate/']:
            return
        # 1.读取当前访问用的session信息,如果能读到,则继续向下执行
        info_dict = request.session.get("username")
        print(info_dict)
        if info_dict:
            return
        # 2.如果没有登录,提示登录
        return redirect('/bossApp/login/')
    def process_response(self,request,response):
        print("UserMW leave here")
        return response

4.校验图片验证码

       通过从session中获取验证码与输入的验证码进行比较

def login(request):
    if request.method == "GET":
        return render(request, 'login.html')
    else:
        username = request.POST.get('username')
        pwd = request.POST.get('password')
        email = request.POST.get('email')
        code = request.POST.get('code')
        # 创建md5对象
        md5 = hashlib.md5()
        # 对字符串进行编码
        md5.update(pwd.encode())
        # 加密
        pwd = md5.hexdigest()
        try:
            # 判段加密后的密码是否相等
            user = User.objects.get(username=username, password=pwd)
            # 邮箱是否正确
            if user.email == email:
                # 邮箱激活
                if user.is_active:
                    # 判段验证码是否正确
                    img_code = request.session.get('imagecode')
                    print(code,img_code)
                    if code.upper() != img_code.upper():
                        return errorResponse(request, '验证码不正确!!')
                    else:
                        # 密码相等的话设置session,保存该用户的一次会话
                        request.session['username'] = user.username
                        # print('session-------username',request.session.get('username'))
                        # 跳转到首页
                        return redirect('/bossApp/home')
                else:
                    return errorResponse(request, '该用户未激活,请先激活!!')
            return errorResponse(request, '邮箱不存在,重新输入!!')
        except:
            return errorResponse(request, '用户名或密码错误!!')

贴一下刷新验证码,使用js重新加载一下验证码的路由就好了
部分html代码

<div style="margin-left: 195px;margin-top: -43px">
       {# 动态生成验证码图片 #}
      <img style="height: 41px" id="img_code" src="/bossApp/codevalidate/">
          </div>
               <div style="margin-right: -195px;margin-top: 3px;">
                  <a href="#" id="refresh-link"
                           style="font-size: 12px;">看不清,换一张</a>

               </div>
         </div>
</div>         

js代码

<script>
document.getElementById("refresh-link").addEventListener("click", function(e) {
    e.preventDefault(); // 阻止默认的链接点击行为
    var imgCode = document.getElementById("img_code");
    imgCode.src = "/bossApp/codevalidate/?t=" + new Date().getTime(); // 添加时间戳来避免缓存
});

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值