zoukankan      html  css  js  c++  java
  • 极验验证码(geetest)和django之间的使用

    极验验证码如何使用

    1. sdk的github地址 git clone https://github.com/GeeTeam/gt3-python-sdk.git

    2. 官网申请账号点此进入,并获取id和key

    3. 项目配置文件

      # GeeTest
      GEETEST_PC_ID = 'b46d1900d0a894591916ea94ea91bd2c'
      GEETEST_PC_KEY = '36fc3fe98530eea08dfc6ce76e3d24c4'
      
    4. geetest 核心文件

      #!coding:utf8
      import sys
      import random
      import json
      import requests
      import time
      from hashlib import md5
      
      if sys.version_info >= (3,):
          xrange = range
      
      VERSION = "3.0.0"
      
      class GeetestLib(object):
          FN_CHALLENGE = "geetest_challenge"
          FN_VALIDATE = "geetest_validate"
          FN_SECCODE = "geetest_seccode"
          GT_STATUS_SESSION_KEY = "gt_server_status"
      
          API_URL = "http://api.geetest.com"
          REGISTER_HANDLER = "/register.php"
          VALIDATE_HANDLER = "/validate.php"
          JSON_FORMAT = False
      
          def __init__(self, captcha_id, private_key):
              self.private_key = private_key
              self.captcha_id = captcha_id
              self.sdk_version = VERSION
              self._response_str = ""
      
      
          def pre_process(self, user_id=None,new_captcha=1,JSON_FORMAT=1,client_type="web",ip_address=""):
              """
              验证初始化预处理.
              //TO DO  arrage the parameter
              """
              status, challenge = self._register(user_id,new_captcha,JSON_FORMAT,client_type,ip_address)
              self._response_str = self._make_response_format(status, challenge,new_captcha)
              return status
      
          def _register(self, user_id=None,new_captcha=1,JSON_FORMAT=1,client_type="web",ip_address=""):
              pri_responce = self._register_challenge(user_id,new_captcha,JSON_FORMAT,client_type,ip_address)
              if pri_responce:
                  if JSON_FORMAT == 1:
                      response_dic = json.loads(pri_responce)
                      challenge = response_dic["challenge"]
                  else:
                      challenge = pri_responce
              else:
                  challenge=" "
              if len(challenge) == 32:
                  challenge = self._md5_encode("".join([challenge, self.private_key]))
                  return 1,challenge
              else:
                  return 0, self._make_fail_challenge()
      
          def get_response_str(self):
              return self._response_str
      
          def _make_fail_challenge(self):
              rnd1 = random.randint(0, 99)
              rnd2 = random.randint(0, 99)
              md5_str1 = self._md5_encode(str(rnd1))
              md5_str2 = self._md5_encode(str(rnd2))
              challenge = md5_str1 + md5_str2[0:2]
              return challenge
      
          def _make_response_format(self, success=1, challenge=None,new_captcha=1):
              if not challenge:
                  challenge = self._make_fail_challenge()
              if new_captcha:
                  string_format = json.dumps(
                      {'success': success, 'gt':self.captcha_id, 'challenge': challenge,"new_captcha":True})
              else:
                  string_format = json.dumps(
                      {'success': success, 'gt':self.captcha_id, 'challenge': challenge,"new_captcha":False})
              return string_format
      
          def _register_challenge(self, user_id=None,new_captcha=1,JSON_FORMAT=1,client_type="web",ip_address=""):
              if user_id:
                  register_url = "{api_url}{handler}?gt={captcha_ID}&user_id={user_id}&json_format={JSON_FORMAT}&client_type={client_type}&ip_address={ip_address}".format(
                          api_url=self.API_URL, handler=self.REGISTER_HANDLER, captcha_ID=self.captcha_id, user_id=user_id,new_captcha=new_captcha,JSON_FORMAT=JSON_FORMAT,client_type=client_type,ip_address=ip_address)
              else:
                  register_url = "{api_url}{handler}?gt={captcha_ID}&json_format={JSON_FORMAT}&client_type={client_type}&ip_address={ip_address}".format(
                          api_url=self.API_URL, handler=self.REGISTER_HANDLER, captcha_ID=self.captcha_id,new_captcha=new_captcha,JSON_FORMAT=JSON_FORMAT,client_type=client_type,ip_address=ip_address)
              try:
                  response = requests.get(register_url, timeout=2)
                  if response.status_code == requests.codes.ok:
                      res_string = response.text
                  else:
                      res_string = ""
              except:
                  res_string = ""
              return res_string
      
          def success_validate(self, challenge, validate, seccode, user_id=None,gt=None,data='',userinfo='',JSON_FORMAT=1):
              """
              正常模式的二次验证方式.向geetest server 请求验证结果.
              """
              if not self._check_para(challenge, validate, seccode):
                  return 0
              if not self._check_result(challenge, validate):
                  return 0
              validate_url = "{api_url}{handler}".format(
                  api_url=self.API_URL, handler=self.VALIDATE_HANDLER)
              query = {
                  "seccode": seccode,
                  "sdk": ''.join( ["python_",self.sdk_version]),
                  "user_id": user_id,
                  "data":data,
                  "timestamp":time.time(),
                  "challenge":challenge,
                  "userinfo":userinfo,
                  "captchaid":gt,
                  "json_format":JSON_FORMAT
              }
              backinfo = self._post_values(validate_url, query)
              if JSON_FORMAT == 1:
                  backinfo = json.loads(backinfo)
                  backinfo = backinfo["seccode"]
              if backinfo == self._md5_encode(seccode):
                  return 1
              else:
                  return 0
      
          def _post_values(self, apiserver, data):
              response = requests.post(apiserver, data)
              return response.text
      
          def _check_result(self, origin, validate):
              encodeStr = self._md5_encode(self.private_key + "geetest" + origin)
              if validate == encodeStr:
                  return True
              else:
                  return False
      
          def failback_validate(self, challenge, validate, seccode):
              """
              failback模式的二次验证方式.在本地对轨迹进行简单的判断返回验证结果.
              """
              if not self._check_para(challenge, validate, seccode):
                  return 0
              validate_result = self._failback_check_result(
                  challenge, validate,)
              return validate_result
      
          def _failback_check_result(self,challenge,validate):
              encodeStr = self._md5_encode(challenge)
              if validate == encodeStr:
                  return True
              else:
                  return False
          def _check_para(self, challenge, validate, seccode):
              return (bool(challenge.strip()) and bool(validate.strip()) and  bool(seccode.strip()))
      
          def _md5_encode(self, values):
              if type(values) == str:
                  values = values.encode()
              m = md5(values)
              return m.hexdigest()
      
    5. 后端代码-获取滑动验证码

      def get(self,request):
              user_id = 'test'
              gt = GeetestLib(settings.GEETEST_PC_ID, settings.GEETEST_PC_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)
      
    6. 后端代码-验证验证码和数据信息

      def post(self,request):
              # 判断用户名和密码不能为空
              name = request.POST.get("username", "").strip()
              if not name:
                  return Response({"status": "fail","msg":"用户名不能为空"})
              password = request.POST.get("password", "").strip()
              if not re.match(r'w{5,16}',password):
                  return Response({"status": "fail", "msg": "密码不合法"})
      
              gt = GeetestLib(settings.GEETEST_PC_ID, settings.GEETEST_PC_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 not result:
                  return Response({"status": "fail","msg":"网络错误"})
      
              # 检查用户是否存在
              userobj = models.Member.objects.filter(name=name).first()
              if not userobj:
                  return Response({"status": "fail", "msg": "用户名或者密码错误"})
              if not check_password(password,userobj.password):
                  return Response({"status": "fail","msg":"用户名或者密码错误"})
      
              # 将name存在session中
              request.session['uname'] = name
              return Response({"status": "success"})
      
    7. 前端js实现

      var handlerPopup = function (captchaObj) {
        // 成功的回调
        captchaObj.onSuccess(function () {
          var validate = captchaObj.getValidate();
          $.ajax({
            url: "/geetest/", // 进行二次验证
            type: "post",
            dataType: "json",
            data: {
              username: $('#username1').val(),
              password: $('#password1').val(),
              geetest_challenge: validate.geetest_challenge,
              geetest_validate: validate.geetest_validate,
              geetest_seccode: validate.geetest_seccode
            },
            success: function (data) {
              if (data && (data.status === "success")) {
                location.href = '/day/';
              } else {
                var html = "<h6>"+data.msg+"</h6>";
                $(".modal-body p").html(html);
                $("#myModal").modal("show");
              }
            }
          });
        });
        $("#popup-submit").click(function () {
          captchaObj.show();
        });
        // 将验证码加到id为captcha的元素里
        captchaObj.appendTo("#popup-captcha");
      };
      // 项目初始化 调用geettest接口
      $.ajax({
        url: "/geetest/?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 // 表示用户后台检测极验服务器是否宕机,一般不需要关注
          }, handlerPopup);
        }
      });
      
    8. 最终实现的效果如图

  • 相关阅读:
    [No0000C9]神秘的掐指一算是什么?教教你也会
    [No0000C8]英特尔快速存储IRST要不要装
    [No0000C7]windows 10桌面切换快捷键,win10
    [No0000C6]Visual Studio 2017 函数头显示引用个数
    [No0000C4]TortoiseSVN配置外部对比工具
    [No0000C5]VS2010删除空行
    [No0000C3]StarUML2 全平台破解方法
    [No0000C2]WPF 数据绑定的调试
    [No0000C1]Excel 删除空白行和空白列VBA代码
    [No0000C0]百度网盘真实地址解析(不用下载百度网盘)20170301
  • 原文地址:https://www.cnblogs.com/wuxiaoshi/p/12331226.html
Copyright © 2011-2022 走看看