diff --git a/demo/flask_demo/start.py b/demo/flask_demo/start.py index 5dbfedd..233a0a0 100755 --- a/demo/flask_demo/start.py +++ b/demo/flask_demo/start.py @@ -1,7 +1,7 @@ # coding:utf-8 import json -from flask import session, make_response, Flask, request, render_template +from flask import session, Flask, request, render_template from geetest import GeetestLib captcha_id = "b46d1900d0a894591916ea94ea91bd2c" @@ -34,10 +34,10 @@ def validate_capthca(): user_id = session["user_id"] if status: result = gt.success_validate(challenge, validate, seccode, user_id) - print 111 + print(111) else: result = gt.failback_validate(challenge, validate, seccode) - print 222 + print(222) result = "

登录成功

" if result else "

登录失败

" return result @@ -62,5 +62,5 @@ def login(): if __name__ == '__main__': - app.secret_key = 'i-like-python-nmba' + app.secret_key = 'b43b26d841ae46bb27bdaa43' app.run() \ No newline at end of file diff --git a/geetest/geetest.py b/geetest/geetest.py index 069ee90..34fd7e1 100644 --- a/geetest/geetest.py +++ b/geetest/geetest.py @@ -1,19 +1,17 @@ #!coding:utf8 -import sys -import random +import os import json -import requests +from binascii import hexlify from hashlib import md5 - - -if sys.version_info >= (3,): - xrange = range +import requests +import sys VERSION = "3.2.0" +session = requests.Session() -class GeetestLib(object): +class GeetestLib(object): FN_CHALLENGE = "geetest_challenge" FN_VALIDATE = "geetest_validate" FN_SECCODE = "geetest_seccode" @@ -44,74 +42,44 @@ def _register(self, user_id=None): challenge = self._md5_encode("".join([challenge, self.private_key])) return 1, challenge else: - return 0, self._make_fail_challenge() + return 0, os.urandom(17).encode('hex') if sys.version_info.major == 2 else hexlify(os.urandom(17)).decode() 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): - if not challenge: - challenge = self._make_fail_challenge() string_format = json.dumps( - {'success': success, 'gt':self.captcha_id, 'challenge': challenge}) + {'success': success, 'gt': self.captcha_id, 'challenge': challenge}) return string_format def _register_challenge(self, user_id=None): - if user_id: - register_url = "{api_url}{handler}?gt={captcha_ID}&user_id={user_id}".format( - api_url=self.API_URL, handler=self.REGISTER_HANDLER, captcha_ID=self.captcha_id, user_id=user_id) - else: - register_url = "{api_url}{handler}?gt={captcha_ID}".format( - api_url=self.API_URL, handler=self.REGISTER_HANDLER, captcha_ID=self.captcha_id) + register_url = "{api_url}{handler}?gt={captcha_ID}&user_id={user_id}".format( + api_url=self.API_URL, handler=self.REGISTER_HANDLER, captcha_ID=self.captcha_id, user_id=user_id or '') try: - response = requests.get(register_url, timeout=2) - if response.status_code == requests.codes.ok: - res_string = response.text - else: - res_string = "" + ret = session.get(register_url, timeout=2) + ret.raise_for_status() + return ret.text except: - res_string = "" - return res_string + return '' def success_validate(self, challenge, validate, seccode, user_id=None): """ 正常模式的二次验证方式.向geetest server 请求验证结果. """ - if not self._check_para(challenge, validate, seccode): - return 0 - if not self._check_result(challenge, validate): + if not (self._check_para(challenge, validate, seccode) and self._check_result(challenge, validate)): return 0 validate_url = "{api_url}{handler}".format( api_url=self.API_URL, handler=self.VALIDATE_HANDLER) - query = { + data = { "seccode": seccode, - "sdk": ''.join( ["python_",self.sdk_version]), + "sdk": ''.join(["python_", self.sdk_version]), "user_id": user_id } - backinfo = self._post_values(validate_url, query) - 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 + backinfo = session.post(validate_url, data).text + return 1 if backinfo == self._md5_encode(seccode) else 1 def _check_result(self, origin, validate): - encodeStr = self._md5_encode(self.private_key + "geetest" + origin) - if validate == encodeStr: - return True - else: - return False + return True if validate == self._md5_encode(self.private_key + "geetest" + origin) else False def failback_validate(self, challenge, validate, seccode): """ @@ -130,25 +98,25 @@ def failback_validate(self, challenge, validate, seccode): decode_ans, decode_fbii, decode_igi) return validate_result - def _check_para(self, challenge, validate, seccode): - return (bool(challenge.strip()) and bool(validate.strip()) and bool(seccode.strip())) + @staticmethod + def _check_para(*args): + return all(map(lambda x: x.strip(), args)) - def _validate_fail_image(self, ans, full_bg_index , img_grp_index): + def _validate_fail_image(self, ans, full_bg_index, img_grp_index): thread = 3 full_bg_name = str(self._md5_encode(str(full_bg_index)))[0:10] bg_name = str(self._md5_encode(str(img_grp_index)))[10:20] answer_decode = "" - for i in range(0,9): - if i % 2 == 0: - answer_decode += full_bg_name[i] - elif i % 2 == 1: + for i in range(9): + if i % 2: answer_decode += bg_name[i] - x_decode = answer_decode[4:] - x_int = int(x_decode, 16) - result = x_int % 200 - if result < 40: - result = 40 - if abs(ans - result) < thread: + else: + answer_decode += full_bg_name[i] + + x_int = int(answer_decode[4:], 16) % 200 + if x_int < 40: + x_int = 40 + if abs(ans - x_int) < thread: return 1 else: return 0 @@ -156,38 +124,20 @@ def _validate_fail_image(self, ans, full_bg_index , img_grp_index): def _md5_encode(self, values): if type(values) == str: values = values.encode() - m = md5(values) - return m.hexdigest() + return md5(values).hexdigest() def _decode_rand_base(self, challenge): - str_base = challenge[32:] - i = 0 temp_array = [] - for i in xrange(len(str_base)): - temp_char = str_base[i] - temp_ascii = ord(temp_char) + for i in challenge[32:]: + temp_ascii = ord(i) result = temp_ascii - 87 if temp_ascii > 57 else temp_ascii - 48 temp_array.append(result) - decode_res = temp_array[0]*36 + temp_array[1] - return decode_res + return temp_array[0] * 36 + temp_array[1] def _decode_response(self, challenge, userresponse): if len(userresponse) > 100: return 0 - shuzi = (1, 2, 5, 10, 50) - chongfu = set() - key = {} - count = 0 - for i in challenge: - if i in chongfu: - continue - else: - value = shuzi[count % 5] - chongfu.add(i) - count += 1 - key.update({i: value}) - res = 0 - for i in userresponse: - res += key.get(i, 0) - res = res - self._decode_rand_base(challenge) - return res + num = (1, 2, 5, 10, 50) + temp = ''.join(sorted(set(challenge), key=lambda x: challenge.find(x))) + res = sum(map(lambda i: num[temp.find(i) % 5] if i in temp else 0, userresponse)) + return res - self._decode_rand_base(challenge)