Fork me on GitHub

Django搭建登录注册功能

极验验证码使用教程

  • 依赖
    • pip install geetest
  • 导入包
    • from geetest import GeetestLib

极验验证功能实战源码

验证源码

# 极验验证码
pc_geetest_id = "d25d66e1eba4a79b97cbe360f4932617"
pc_geetest_key = "5adc3a6f063632aff82ea78a16db6b03"


# 处理极验 获取验证码的视图
def get_geetest(request):
    user_id = 'lxgzhw@163.com'
    gt = GeetestLib(pc_geetest_id, pc_geetest_key)
    status = gt.pre_process(user_id)
    request.session[gt.GT_STATUS_SESSION_KEY] = status
    request.session["user_id"] = user_id
    response_str = gt.get_response_str()
    return HttpResponse(response_str)

前端JavaScript源码

<!-- 引入封装了failback的接口--initGeetest -->
<script src="http://static.geetest.com/static/tools/gt.js"></script>
<script>
    $(function () {
        // 极验 发送登录数据的
        var handlerPopup = function (captchaObj) {
            // 成功的回调
            captchaObj.onSuccess(function () {
                var validate = captchaObj.getValidate();
                // 1. 取到用户填写的用户名和密码 -> 取input框的值
                var username = $("#id_username").val();
                var password = $("#id_password").val();
                $.ajax({
                    url: "/blog/login/", // 进行二次验证
                    type: "post",
                    dataType: "json",
                    data: {
                        username: username,
                        password: password,
                        csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                        geetest_challenge: validate.geetest_challenge,
                        geetest_validate: validate.geetest_validate,
                        geetest_seccode: validate.geetest_seccode
                    },
                    success: function (data) {
                        if (data.status) {
                            // 有错误,在页面上提示
                            $(".text-danger").text(data.msg);
                        } else {
                            // 登陆成功
                            location.href = data.msg;
                        }
                    }
                });
            });
            // 将验证码加到id为captcha的元素里
            captchaObj.appendTo("#popup-captcha");
            // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html
        };
        // 当input框获取焦点时将之前的错误清空
        $("#id_username,#id_password").focus(function () {
            // 将之前的错误清空
            $(".text-danger").text("");
        });

        // 验证开始需要向网站主后台获取id,challenge,success(是否启用failback)
        $.ajax({
            url: "/pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存
            type: "get",
            dataType: "json",
            success: function (data) {
                // 使用initGeetest接口
                // 参数1:配置参数
                // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件
                initGeetest({
                    gt: data.gt,
                    challenge: data.challenge,
                    product: "popup", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
                    offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注
                    // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config
                }, handlerPopup);
            }
        })
    })
</script>

后台登录视图实战源码
# 用户登录
def login(request):
    form_obj = LoginForm()
    if request.method == "POST":
        # 初始化一个给AJAX返回的数据
        ret = {"status": 0, "msg": ""}
        # 从提交过来的数据中 取到用户名和密码
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        # 获取极验 滑动验证码相关的参数
        gt = GeetestLib(pc_geetest_id, pc_geetest_key)
        challenge = request.POST.get(gt.FN_CHALLENGE, '')
        validate = request.POST.get(gt.FN_VALIDATE, '')
        seccode = request.POST.get(gt.FN_SECCODE, '')
        status = request.session[gt.GT_STATUS_SESSION_KEY]
        user_id = request.session["user_id"]

        if status:
            result = gt.success_validate(challenge, validate, seccode, user_id)
        else:
            result = gt.failback_validate(challenge, validate, seccode)
        if result:
            # 验证码正确
            # 利用auth模块做用户名和密码的校验
            user = auth.authenticate(username=username, password=pwd)
            if user:
                # 用户名密码正确
                # 给用户做登录
                auth.login(request, user)  # 将登录用户赋值给 request.user
                ret["msg"] = "/blog/index/"
            else:
                # 用户名密码错误
                ret["status"] = 1
                ret["msg"] = "用户名或密码错误!"
        else:
            ret["status"] = 1
            ret["msg"] = "验证码错误"

        return JsonResponse(ret)
    return render(request, 'blog/login.html', {
        'form_obj': form_obj,
    })
Python

注册功能实战源码

表单 forms.py

# 注册表单
class RegisterForm(forms.Form):
    username = forms.CharField(
        required=True,
        max_length=16,
        label='用户名',
        error_messages={
            'max_length': '用户名应为2-16位',
            'required': '用户名不能为空'
        },
        widget=forms.widgets.TextInput(
            attrs={
                'class': 'form-control',
            }
        )
    )
    password = forms.CharField(
        max_length=16,
        min_length=6,
        required=True,
        label='密码',
        widget=forms.widgets.PasswordInput(
            attrs={
                'class': 'form-control',
            },
            render_value=True,
        ),
        error_messages={
            'min_length': '密码最少为6位',
            'max_length': '密码最多不超过16位',
            'required': '密码不能为空',
        }
    )
    re_password = forms.CharField(
        max_length=16,
        min_length=6,
        required=True,
        label='确认密码',
        widget=forms.widgets.PasswordInput(
            attrs={
                'class': 'form-control',
            },
            render_value=True,
        ),
        error_messages={
            'min_length': '确认密码最少为6位',
            'max_length': '确认密码最多不超过16位',
            'required': '确认密码不能为空',
        }
    )
    phone = forms.CharField(
        required=True,
        min_length=11,
        max_length=11,
        label='手机号',
        widget=forms.widgets.EmailInput(
            attrs={
                'class': 'form-control',
            }
        ),
        error_messages={
            'required': '手机号不能为空',
            'min-length': '手机号至少11位',
            'max-length': '手机号最多11位',
        }

    )

    email = forms.EmailField(
        required=True,
        label='邮箱',
        widget=forms.widgets.EmailInput(
            attrs={
                'class': 'form-control',
            }
        ),
        error_messages={
            'required': '邮箱不能为空',
            'invalid': '邮箱格式不正确',
        }

    )

    # 重写全局钩子函数,对确认密码做校验
    def clean(self):
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')

        if password and re_password != password:
            self.add_error('re_password', ValidationError('两次密码不一致'))
        else:
            return self.cleaned_data




视图 views.py

# 用户注册
def register(request):
    form_obj = RegisterForm()
    if request.method == 'POST':
        form_obj = RegisterForm(request.POST)
        if form_obj.is_valid():
            form_obj.cleaned_data.pop('re_password')
            # 保存图片 Django会自己处理同名图片,无需我们担心
            avatar_img = request.FILES.get('avatar')
            UserInfo.objects.create_user(**form_obj.cleaned_data, avatar=avatar_img)
            return redirect(index)
    return render(request, 'blog/register.html', {
        'form_obj': form_obj,
    })

前端register.html
<div class="row">
    <div class="col-md-6 col-md-offset-3">

        <form novalidate action="/blog/register/" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <div class="form-group">
                <label for="{{form_obj.username.id_for_label}}">{{form_obj.username.label}}</label>
                {{form_obj.username}}
                <span class="text-danger">{{form_obj.username.errors.0}}</span>
            </div>
            <div class="form-group">
                <label for="{{form_obj.password.id_for_label}}">{{form_obj.password.label}}</label>
                {{form_obj.password}}
                <span class="text-danger">{{form_obj.password.errors.0}}</span>
            </div>
            <div class="form-group">
                <label for="{{form_obj.re_password.id_for_label}}">{{form_obj.re_password.label}}</label>
                {{form_obj.re_password}}
                <span class="text-danger">{{form_obj.re_password.errors.0}}</span>
            </div>
            <div class="form-group">
                <label for="{{form_obj.phone.id_for_label}}">{{form_obj.phone.label}}</label>
                {{form_obj.phone}}
                <span class="text-danger">{{form_obj.phone.errors.0}}</span>
            </div>
            <div class="form-group">
                <label for="{{form_obj.email.id_for_label}}">{{form_obj.email.label}}</label>
                {{form_obj.email}}
                <span class="text-danger">{{form_obj.email.errors.0}}</span>
            </div>

            <div class="form-group">
                <label>头像</label> <br>
                <label for="ufile">
                    <img src="/static/blog/img/default.png/" alt="头像" id="u_img">
                </label>
                <input type="file" name="avatar" id="ufile" style="display: none;">
                <p class="help-block">请上传jpg/png/gif格式的图片,大小不得超过1M</p>
            </div>
            <div class="checkbox">
                <label>
                    <input type="checkbox" name="isAgree"> 同意注册协议
                </label>
            </div>
            <button id="reg_submit" type="submit" class="btn btn-default">注册</button>
        </form>
    </div>
</div>
Python

头像预览功能实战源码

//头像预览功能
        $('#ufile').change(function () {
            let fileReader = new FileReader()
            fileReader.readAsDataURL(this.files[0])
            fileReader.onload = function () {
                $('#u_img').attr({
                    src: fileReader.result,
                })
            }
        })
posted @ 2019-03-11 11:20  seymourgao  阅读(194)  评论(0编辑  收藏  举报