2022暑期实践(Django教程学习记录)(第四周6)P56图片验证码(校验)

P56图片验证码(校验)

将生成的动态验证码存入session中:
所有用户都访问同一个url生成动态验证码,需要给不同用户存到不同的位置

def image_code(request):
    from app03_phone_number_management.utils.code import check_code
    img, code_string = check_code()
    # 将突变验证码写入到session,设置60s过期
    request.session['image_code'] = code_string
    request.session.set_expiry(60)
    print(code_string)
    from io import BytesIO
    stream = BytesIO()
    img.save(stream, 'png')
    return HttpResponse(stream.getvalue())

LoginForm类重写:

class LoginForm(forms.Form):
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        required=True,
    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(
            attrs={'class': 'form-control'},
            render_value=True,
        ),
        required=True,
    )
    code = forms.CharField(
        label="验证码",
        widget=forms.TextInput(
            attrs={'class': 'form-control'},
        ),
        required=True,
    )
# 在attr中向前端添加class样式,也可以多继承
    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        from app03_phone_number_management.utils.encrypt import md5
        return md5(pwd)

对应login前端的Form自动生成验证码的输入框

{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <style>
        .account {
            width: 400px;
            border: 1px solid #dddddd;
            border-radius: 5px;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }

        .account h2 {
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>

<body>
<div class="account">
    <h2>用户登录</h2>
    <form method="POST" novalidate>
        {% csrf_token %}
        <div class="form-group">
            <label for="exampleInputEmail">用户名</label>
            {#            <input type="text" class="form-control" placeholder="用户名">#}
            {{ form.username }}
            <span style="color: red">{{ form.username.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label>密码</label>
            {#            <input type="password" class="form-control" placeholder="密码">#}
            {{ form.password }}
            <span style="color: red">{{ form.password.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label for="id_code">图片验证码</label>
            <div class="row">
                <div class="col-xs-7">
                    {{ form.code }}
                    <span style="color: red">{{ form.code.errors.0 }}</span>

                </div>
                <div class="col-xs-5">
                    <img id="image_code" src="/image_code/" style="width: 125px;">
                </div>
            </div>
        </div>
        <input type="submit" value="登 录" class="btn btn-primary">
    </form>
</div>
</body>
</html>

登录逻辑加入验证码校验逻辑:
!!!一定要把session超时时间改回来

def login(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request, 'login.html', {'form': form})
    # else:
    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 校验验证码
        # 使用pop方法的原因:在数据库中检验没有code字段,校验完要剔除
        user_input_code = form.cleaned_data.pop('code')
        code = request.session.get('session', "")
        if code.upper() != user_input_code.upper():
            form.add_error('code', "验证码错误")
            return render(request, 'login.html', {'form': form})
        # test
        # print(form.cleaned_data)
        # return HttpResponse('提交成功')

        # 验证校验:
        # admin_object = models.Admin.objects.filter(username=form.cleaned_data['username'], password=form.cleaned_data['password']).first()
        # 定义类时的字段名要和数据库中的一致
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            form.add_error("password", "用户名或密码错误")
            return render(request, 'login.html', {'form': form})
        # else用户名正确:
        request.session['info'] = {
            'id': admin_object.id,
            'name': admin_object.username,
        }
        # 7天免登录
        request.session.set_expiry(60*60*24*7)
        return redirect('/admin_list/')
    # else:
    return render(request, 'login.html', {'form': form})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值