UVerifyObject.py 4.1 KB

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