django登录源码与第三方登录验证源码 - Go语言中文社区

django登录源码与第三方登录验证源码


引言

这篇我想总结一下关于登录的一些方式,然后主要以三种方式实现登录验证,第一种是用原始验证码,第二种是用极验验证码,第三种是云通讯的短信验证码门下面就来介绍具体的实现步骤。

自制图片验证码

准备

自备一张验证码的图片,加一个文字板式文件。

后端实现

def login(request):
    # 登陆是将信息输入进去
    if request.method == "POST":
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        valid_code = request.POST.get("valid_code")
        res = {"statu":0,"msg":None}
        valid_str = request.session.get("valid_str")
        print(valid_str)
        # 验证验证码是否相同
        if valid_code.upper() == valid_str.upper():
            # 验证是否有这个用户
            user = auth.authenticate(username=username,password=pwd)
            # 通过认证,登陆成功,获取当前用户
            if user:
                res["msg"] = "/index/"
                auth.login(request,user)
            else:
                res["status"] = 1
                res["msg"]= "帐号或密码错误"

        else:
            res["status"] = 1
            res["msg"] = "验证码错误"
        return JsonResponse(res)
    return render(request,"login.html")



def index(request):
    return render(request, "index.html")



# 这里是生成图片验证码的地方
def get_valid_img(request):
    from PIL import ImageDraw
    from PIL import Image
    import random
    def random_color():
        return random.randint(0,255),random.randint(0,255),random.randint(0,255)

    img_obj = Image.new(
        'RGB',
        (220, 35),
        random_color()
    )
    # 在生成的图片上写字符
    # 生成一个图片画笔对象
    draw_obj = ImageDraw.Draw(img_obj)
    # 加载字体文件, 得到一个字体对象
    font_obj = ImageFont.truetype("static/font/kumo.ttf", 28)
    # 开始生成随机字符串并且写到图片上
    tmp_list = []
    for i in range(5):
        u = chr(random.randint(65, 90))  # 生成大写字母
        l = chr(random.randint(97, 122))  # 生成小写字母
        n = str(random.randint(0, 9))  # 生成数字,注意要转换成字符串类型

        tmp = random.choice([u, l, n])
        tmp_list.append(tmp)
        draw_obj.text((20+40*i, 0), tmp, fill=random_color(), font=font_obj)

    print("生成的验证码".center(120, "="))
    valid_str="".join(tmp_list)  # "xxxx"
    print("valid_str",valid_str)

    request.session["valid_str"]=valid_str

    # 不需要在硬盘上保存文件,直接在内存中加载就可以
    from io import BytesIO
    io_obj = BytesIO()
    # 将生成的图片数据保存在io对象中
    img_obj.save(io_obj, "png")
    # 从io对象里面取上一步保存的数据
    data = io_obj.getvalue()
    return HttpResponse(data)

前端实现

部分代码如下:

    // 当input框获取焦点时将之前的错误清空
    $("#username,#password").focus(function () {
        // 将之前的错误清空
        $(".login-error").text("");
    });

    // 点击验证码图片 刷新验证码
    $("#valid-img").click(function () {
        $(this)[0].src += "?";
    })

演示效果

在这里插入图片描述

加干扰

如果觉得上面的图形验证码比较简单,还能加入干扰线,加大了反爬的难度,但也给用户增加了难度。

    # 加干扰线
    width = 220  # 图片宽度(防止越界)
    height = 35
    for i in range(5):
        x1 = random.randint(0, width)
        x2 = random.randint(0, width)
        y1 = random.randint(0, height)
        y2 = random.randint(0, height)
        draw_obj.line((x1, y1, x2, y2), fill=random_color())

使用极验验证码登录


极验后台下申请免费账户

在这里插入图片描述

这里登录成功后进入极验的后台,然后点击新增验证,名字还有域名可以随便填写,如果是单单拿来测试的话,比如说这里我就取名为测试自备,另外就是官方的SDK中也有提供相关的测试用例key和id,如果不想注册这个平台的账号,可以用我的测试用例。另外如果需要本篇全部的源码,可以加我QQ

后端实现


# 申明极验后台获取的测试账户
pc_geetest_id = "5e1e39abb2a23389a88a37ff03aa0d46"
pc_geetest_key = "047953424e4c2d9a83c5d754adedfd94"

def login(request):
    # if request.is_ajax():  # 如果是AJAX请求
    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)
                ret["msg"] = "/index/"
            else:
                # 用户名密码错误
                ret["status"] = 1
                ret["msg"] = "用户名或密码错误!"
        else:
            ret["status"] = 1
            ret["msg"] = "验证码错误"

        return JsonResponse(ret)
    return render(request, "login.html")

# 处理极验 获取验证码的视图
def get_geetest(request):
    user_id = 'test'
    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)


def index(request):
    return render(request,"index.html")

前端实现

这里是部分核心代码,其实也就是极验的第三方提供的前端页面的核心代码:

    $.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);
        }
    })

演示效果

在这里插入图片描述

这只是滑块的登录验证码的形式,极验验证码还有另外的三种方式,这些都可以从官网的登录demo中看到,在这里我们就只演示这种滑动的。

使用云通讯登录

登录云通讯控制台

在这里插入图片描述

这里面有五个参数需要考虑,另外在开发流程里面找到了python的demo,然后不同于极验,这个就需要另外去配置了,下面就是我的云通讯的一些配置,其中我是将token省略了,基本上这个还是保密的,因为一个手机号只能绑定一个。

在这里插入图片描述

后端实现

def send_code(request):
    # 取到请求值中的内容
    mobile = request.POST.get("mobile")
    ret = {"errno": 0, "errmsg": None}
    if not mobile:
        ret["status"] = 1
        ret["msg"] = "参数不全"

    # 2. 校验手机号是正确
    if not re.match("^1[3578][0-9]{9}$", mobile):
        ret["status"] = 1
        ret["msg"] = "提示手机号不正确"

    user = UserInfo.objects.filter(telephone=mobile).first()
    if not user:
        ret["status"] = 1
        ret["msg"] = "没有该用户"
    # 5. 生成发送短信的内容并发送短信
    result = random.randint(0, 999999)
    sms_code = "%06d" % result
    result = CCP().send_template_sms(mobile, [sms_code, 300 / 60], "1")
    # 6. redis中保存短信验证码内容
    global redis_store
    redis_store = StrictRedis(host="127.0.0.1",
                              port=6379,
                              db=9,
                              decode_responses=True
                              )

    try:
        redis_store.set("SMS_" + mobile, sms_code, 300)
    except Exception as e:
        ret["status"] = 1
        ret["msg"] = "保存短信验证码失败"

    # 7. 返回发送成功的响应
    return JsonResponse(ret)

前端实现

暂时无,这里留个坑位,以待以后回来填。

云通讯的方式对我来说有些不友好,首先是问题一大堆。注册这个平台的时候,验证码图片换了十多张才勉强对了一遍,是真看不清。。。另外就是注册完后,参数有点多,还有就是沙箱环境问题,这里的坑是,如果不改的话程序都跑不出来。。。必须要生产环境,另外还有一大堆bug,留待以后吧。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/submarineas/article/details/84634008
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢