UVerifyObject.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import base64
  4. import hashlib
  5. import hmac
  6. import json
  7. import logging
  8. import random
  9. import string
  10. import time
  11. import requests
  12. from datetime import datetime, timedelta
  13. class UVerifyObject:
  14. '''
  15. 【友盟+】智能认证 U-Verify(一键登录)
  16. 开发文档:
  17. https://developer.umeng.com/docs/143070/detail/144785
  18. https://developer.umeng.com/docs/143070/detail/144783
  19. '''
  20. def __init__(self, token):
  21. # aliyun config
  22. self.ali_appkey = '204024884'
  23. self.ali_app_secret = 'lD7AXxc0ji0HzrNXZmfJaz3AecAboItD'
  24. # umeng config
  25. self.host_url = 'https://verify5.market.alicloudapi.com'
  26. self.path_url = '/api/v1/mobile/info'
  27. self.umeng_app_key = '5d8da0670cafb2a6b5000bc3'
  28. self.token = token
  29. self.phone = ''
  30. self.body_data_str = json.dumps({'token': self.token})
  31. content_md5_str = base64.b64encode(hashlib.md5(self.body_data_str.encode("UTF-8")).digest()).decode("UTF-8")
  32. now_date_time = datetime.utcnow() + timedelta(hours=8)
  33. timestamp = str(int(time.mktime(now_date_time.timetuple()) * 1000))
  34. sign_headers_dict = {
  35. 'X-Ca-Key': self.ali_appkey,
  36. 'X-Ca-Stage': 'RELEASE',
  37. 'X-Ca-Timestamp': timestamp,
  38. 'X-Ca-Version': '1'
  39. }
  40. sign_headers_str = ''
  41. for key in sorted(sign_headers_dict.keys()):
  42. value = sign_headers_dict[key]
  43. sign_headers_str = sign_headers_str + key + ':' + value + '\n'
  44. sign_dict = {
  45. 'HTTPMethod': 'POST',
  46. 'Accept': 'application/json',
  47. 'Content-MD5': content_md5_str,
  48. 'Content-Type': 'application/json; charset=UTF-8',
  49. 'Date': None,
  50. 'Headers': sign_headers_str,
  51. 'Url': self.path_url + '?' + 'appkey=' + self.umeng_app_key,
  52. }
  53. string_to_sign = ""
  54. for key in sign_dict.keys():
  55. value = sign_dict[key]
  56. if key not in ['Headers', 'Url']:
  57. if value:
  58. string_to_sign = string_to_sign + value + "\n"
  59. else:
  60. string_to_sign = string_to_sign + "\n"
  61. else:
  62. string_to_sign = string_to_sign + value
  63. key_bytes = self.ali_app_secret.encode('utf-8')
  64. text_bytes = string_to_sign.encode('utf-8')
  65. hash_bytes = hmac.new(key_bytes, text_bytes, hashlib.sha256).digest()
  66. signature_str = base64.b64encode(hash_bytes).decode('utf-8')
  67. nonce_str = self.generate_code(8) + '-' + self.generate_code(4) + '-' + self.generate_code(4) + '-' + \
  68. self.generate_code(4) + '-' + self.generate_code(12)
  69. self.headers_dict = {
  70. 'Content-Type': 'application/json; charset=UTF-8',
  71. 'Accept': 'application/json',
  72. 'X-Ca-Version': '1',
  73. 'X-Ca-Signature-Headers': 'X-Ca-Version,X-Ca-Stage,X-Ca-Key,X-Ca-Timestamp',
  74. 'X-Ca-Stage': 'RELEASE',
  75. 'X-Ca-Key': self.ali_appkey,
  76. 'X-Ca-Timestamp': timestamp,
  77. 'X-Ca-Nonce': nonce_str,
  78. 'Content-MD5': content_md5_str,
  79. 'X-Ca-Signature': signature_str
  80. }
  81. self.request_url = self.host_url + self.path_url + '?' + 'appkey=' + self.umeng_app_key
  82. def generate_code(self, length):
  83. key = string.digits + 'abcdef'
  84. str_list = random.sample(key + key, length) # length >= len(key+key)
  85. result_str = ''.join(str_list)
  86. return result_str
  87. def verify_request(self):
  88. logger = logging.getLogger('info')
  89. logger.info('request_url: {}, data: {}, headers: {}'.format(self.request_url, self.body_data_str, self.headers_dict))
  90. response = requests.post(url=self.request_url, data=self.body_data_str.encode("UTF-8"), headers=self.headers_dict)
  91. logger.info('response: {}, headers: {}, text: {}'.format(response, response.headers, response.text))
  92. # 替换字符串,防止将字符串转为字典时报错
  93. res_text = response.text.replace('true', '"true"').replace('false', '"false"').replace('null', '"null"')
  94. logger.info('res_text: {}'.format(res_text))
  95. res = eval(res_text)
  96. print(res['success'])
  97. if res['success'] == 'false':
  98. return False
  99. self.phone = res['data']['mobile'] # 获取手机号
  100. return True