tengke 发表于 2023-6-14 17:13:39

验证码校验


##验证码功能
def yzm(request):
    img,code_staing = check_code()
    print(code_staing)

    #写入到自己的session中
    request.session['image_code']=code_staing
    #图片60秒超时
    request.session.set_expiry(60)

    stream = BytesIO()
    img.save(stream, 'png')
    stream.getvalue()
    returnHttpResponse(stream.getvalue())



def login(request):
    if request.method == "GET":
      form = Logina()
      return render(request,"login.html",{"form":form})
    form = Logina(data=request.POST)
    if form.is_valid():
      # print(form.cleaned_data)
      # pd = models.admin.objects.filter(username=form.cleaned_data["username"],password=form.cleaned_data["password"])
      print(form.cleaned_data,"1")
      # 可以查看到登陆界面的用户名和密码 验证码信息
      userinputcode = form.cleaned_data.pop('yzm')
      print(userinputcode,"2")
      # 剔除 yzm信息
      yzm = request.session.get('image_code', "")
      print(yzm,"3")
      if yzm != userinputcode:
            form.add_error("yzm", "验证码错误")
            return render(request, "login.html", {"form": form})
      pd = models.admin.objects.filter(**form.cleaned_data).first()
      if not pd:
            form.add_error("password","用户名密码错误")
            return render(request, "login.html", {"form": form})
      request.session["info"] = {"id":pd.id,"name":pd.username}
      return redirect("http://127.0.0.1:8000/view/")
    # return render(request, "dl.html", {"form": form})



验证码 密码 无论正确还是错误都无法正常登陆   也没有提示
大佬有时间麻烦看看

sfqxx 发表于 2023-6-14 17:13:40

根据您提供的代码,我可以看出一些问题可能导致无法正常登录:

1. 在`yzm()`函数中,应该返回响应对象而不是输出到控制台。可以使用`HttpResponse`将图像数据直接返回给浏览器。

2. 在`yzm()`函数中,您没有传递要使用的验证码长度作为参数来生成验证码字符串。在某些情况下,这会导致错误的验证码匹配,因为您假定用户输入与服务器生成的验证码长度相同。

3. 在`login()`函数中,您从表单中移除了验证码数据,但没有进行验证,因此`form.is_valid()`总是返回True。您需要添加以下代码来验证验证码字段:

   
    userinputcode = form.cleaned_data["yzm"]
    yzm_stored = request.session.get("image_code")
    if not yzm_stored or yzm_stored.lower() != userinputcode.lower():
      form.add_error("yzm", "验证码错误")
      return render(request, "login.html", {"form": form})

4. 您应该考虑在模板上显示表单错误。最好的方法是使用`{{ form.as_p }}`或`{{ form.as_table }}`将表单呈现为HTML,并使用`{{ form.field_name.errors }}`将任何相关错误消息呈现为HTML。

5. 最后,在`yzm()`函数和`login()`函数中,您似乎没有检查请求方法是否为HTTP GET或POST。在`yzm()`函数中,您只需要处理GET请求以显示验证码图像。在`login()`函数中,您需要处理GET和POST请求。可以使用`request.method == "GET"`或`request.method == "POST"`来检查请求方法。

鉴于以上问题,我们可以对您的代码进行如下修改:


import random
from io import BytesIO
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .forms import Logina


def check_code(length=4):# 指定默认验证码长度
    """生成指定长度的随机验证码

    :param length: 验证码长度,默认为4
    :return: 生成的验证码字符串
    """
    # 去掉了字符串中的数字0和字母O,避免用户输入时容易混淆
    code_list = ["1", "2", "3", "4", "5", "6", "7", "8", "9",
               "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
               "k", "m", "n", "p", "q", "r", "s", "t", "u", "v",
               "w", "x", "y", "z"]
    # 通过 random.sample() 方法从列表中随机选择 length 个元素作为验证码的字符
    return ''.join(random.sample(code_list, length))


def yzm(request):
    code = check_code()
    # 将生成的验证码保存到当前会话 session 中
    request.session["image_code"] = code
    # 创建画布和画笔,开始绘制验证码图片
    img_size = (130, 40)
    image = Image.new("RGB", img_size, (200, 200, 200))
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype('arial.ttf', 36)# 使用默认字体并设置字号为36
    # 绘制每个字符
    for i in range(len(code)):
      draw.text((10 + 30 * i, 0), code, font=font, fill=(0, 0, 0))# 每个字符在 x 坐标上递增30
    # 将画布中的图像导出为二进制数据流,并返回给浏览器
    buffer = BytesIO()
    image.save(buffer, "png")
    return HttpResponse(buffer.getvalue(), content_type="image/png")


def login(request):
    if request.method == 'POST':
      form = Logina(request.POST)
      userinputcode = form.cleaned_data["yzm"]
      yzm_stored = request.session.get("image_code", "")```
      if not yzm_stored or yzm_stored.lower() != userinputcode.lower():
            form.add_error("yzm", "验证码错误")
            return render(request, "login.html", {"form": form})

      if form.is_valid():
            # 如果表单数据有效,则可以进行登录操作
            username = form.cleaned_data["username"]
            password = form.cleaned_data["password"]
            # 登录处理...
            ...
    else:
      form = Logina()
    return render(request, "login.html", {"form": form})

在上述代码中,我们做了以下更改:

1. 修改了`yzm()`函数,使其返回响应对象,并将验证码长度作为参数传递。

2. 在`login()`函数中添加了对验证码的验证,使用`form.add_error()`方法将错误信息添加到表单中,最后呈现表单和错误消息。如果没有错误,则可以继续进行登录操作。

3. 在模板中使用`{{ form.as_p }}`或`{{ form.as_table }}`来呈现表单,并使用`{{ form.field_name.errors }}`来呈现任何相关错误消息。

4. 检查请求方法是HTTP GET还是POST,以便正确处理表单提交和验证码生成。

希望这些修改能够帮助您解决登录问题。

isdkz 发表于 2023-6-14 17:44:03

您的代码看起来没有明显的错误,验证码功能和登录功能也基本正确,这可能是由于其他原因导致的。下面是一些可能的问题和解决方案:

1. 浏览器缓存和Cookie问题:尝试清除浏览器缓存和Cookie,因为这可能影响session的处理。

2. Django Session设置问题:确保Django的session功能已正确设置,并且数据库正在运行。

3. 验证的敏感性:验证验证码时,如果您的生成器生成的验证码和用户输入的验证码大小写不同,那么验证可能会失败。为了解决这个问题,您可以将生成的验证码和用户输入的验证码都转换为小写或大写。

4.check_code() 函数问题:在您的 yzm 函数中,确保 check_code() 函数返回的是一个验证码图像和正确的验证码字符串。

5. 模型查找问题:在您的 login 函数中,确保 models.admin.objects.filter(**form.cleaned_data).first() 正确返回了预期的用户。

6. 服务器问题:确认你的服务器是否在正常运行,因为这也可能影响你的验证码生成和session的处理。

7. 表单验证问题:确保您的 Logina 表单正确地执行了所有必要的验证。

希望以上建议能帮到你,如果问题仍然存在,请提供更多详细的错误信息,以便我们可以更准确地找到问题。

tengke 发表于 2023-6-14 18:05:50

def login(request):
    if request.method == "GET":
      form = Logina()
      return render(request,"login.html",{"form":form})
    form = Logina(data=request.POST)
    if form.is_valid():
      # print(form.cleaned_data)
      # pd = models.admin.objects.filter(username=form.cleaned_data["username"],password=form.cleaned_data["password"])

      userinputcode = form.cleaned_data.pop('yzm')
      yzm = request.session.get('image_code', "")
      if yzm.upper() != userinputcode.upper():
            form.add_error("yzm","验证码错误")
            return render(request, "login.html", {"form": form})
      pd = models.admin.objects.filter(**form.cleaned_data).first()
      if not pd:
            form.add_error("password","用户名密码错误")
            return render(request, "login.html", {"form": form})
      request.session["info"] = {"id":pd.id,"name":pd.username}
      return redirect("http://127.0.0.1:8000/view/")
    return render(request, "user_add.html", {"form": form})



这个代码有个问题
验证码与后台提供的 或者web界面显示的   输入不一致 也可以进入
进入后 点击任何的界面都要重新登陆

sfqxx 发表于 2023-6-14 18:50:41

@不二如是 审核我发的帖子

不二如是 发表于 2023-6-14 18:59:35

sfqxx 发表于 2023-6-14 18:50
@不二如是 审核我发的帖子

好滴{:10_330:}

sfqxx 发表于 2023-6-17 12:03:08

不二如是 发表于 2023-6-14 18:59
好滴

谢谢{:10_279:}
页: [1]
查看完整版本: 验证码校验