TokenManager.py 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. # -*- coding: utf-8 -*-
  2. from datetime import datetime
  3. from calendar import timegm
  4. from Model.models import AuthToken_Token, Device_User
  5. import time, base64, hmac, random, string,simplejson as json
  6. import traceback
  7. from django.utils.timezone import utc
  8. import datetime as utdatetime
  9. from Service.ResponseService import ResponseFormal
  10. from Ansjer.config import EXPIRATION_DELTA,REFRESH_EXPIRATION_DELTA
  11. def SQLManager(content):
  12. tokenID_id = content.get('tokenID_id', None)
  13. if tokenID_id != None:
  14. tokenIDValid = AuthToken_Token.objects.filter(tokenID_id=tokenID_id)
  15. if tokenIDValid:
  16. try:
  17. content.pop('tokenID_id')
  18. tokenIDValid.update(**content)
  19. tokenIDValid.update(last_update=utdatetime.datetime.utcnow().replace(tzinfo=utc).astimezone(utc))
  20. except Exception as e:
  21. errorInfo = traceback.format_exc()
  22. print('更新Token错误: %s ' % errorInfo)
  23. return ResponseFormal(302,{'details':repr(e)})
  24. else:
  25. return ResponseFormal(0)
  26. else:
  27. try:
  28. authToken = AuthToken_Token(**content)
  29. authToken.save()
  30. except Exception as e:
  31. errorInfo = traceback.format_exc()
  32. print('添加Token错误: %s ' % errorInfo)
  33. return ResponseFormal(301,{'details':repr(e)})
  34. else:
  35. return ResponseFormal(0)
  36. else:
  37. return ResponseFormal(312)
  38. class JSONTokenManager:
  39. def __init__(self):
  40. self.iCode = ''
  41. self.errormsg = ''
  42. self.accessDict = {}
  43. self. refreshDict = {}
  44. def getSalt(self, strLen = 6):
  45. """
  46. 获取指定长度strLen的字符串
  47. :param strLen:
  48. :return: 返回获取到指定长度的字符串
  49. """
  50. salt = ''.join(random.sample(string.ascii_letters + string.digits, strLen))
  51. return salt
  52. def generate_AToken(self, JSON , iCode):
  53. """
  54. :param JSON:
  55. :param iCode:
  56. :return:
  57. """
  58. orig_iat = datetime.utcnow().utctimetuple()
  59. exp_at = (datetime.utcnow() + EXPIRATION_DELTA).utctimetuple()
  60. exp_rt = (datetime.utcnow() + REFRESH_EXPIRATION_DELTA).utctimetuple()
  61. userJSON = json.loads(JSON)
  62. expDict = {'orig_iat': timegm(orig_iat), 'exp_at': timegm(exp_at), 'exp_rt': timegm(exp_rt)}
  63. userJSON.update(expDict)
  64. exp_rtJSON = json.dumps(userJSON, ensure_ascii=False)
  65. userJSON.pop('exp_rt')
  66. exp_atJSON = json.dumps(userJSON, ensure_ascii=False)
  67. print(exp_rtJSON, exp_atJSON)
  68. hmac_at = hmac.new(exp_atJSON.encode('utf-8'), iCode.encode('utf-8')).hexdigest()
  69. hmac_rt = hmac.new(exp_rtJSON.encode('utf-8'), iCode.encode('utf-8')).hexdigest()
  70. access_token = exp_atJSON + '&' + hmac_at
  71. refresh_token = exp_rtJSON + '&' + hmac_rt
  72. b64_access_token = base64.urlsafe_b64encode(access_token.encode("utf-8"))
  73. b64_refresh_token = base64.urlsafe_b64encode(refresh_token.encode("utf-8"))
  74. tokenDict = {'access_token': b64_access_token.decode('utf-8'), 'refresh_token': b64_refresh_token.decode('utf-8'), \
  75. 'iCode': iCode, 'mCode': userJSON.get('mCode', '')}
  76. tokenDict['tokenID_id'] = userJSON.get('userID', None)
  77. print(tokenDict)
  78. sqlJSON = SQLManager(content=tokenDict)
  79. sqlDict = json.loads(sqlJSON)
  80. error_code = sqlDict.get('error_code', None)
  81. if error_code != None and error_code == 0:
  82. b64_alist = list(b64_access_token.decode('utf-8'))
  83. b64_alist.insert(12, self.getSalt(strLen=6))
  84. b64_atoken = ''.join(b64_alist)
  85. b64_rflist = list(b64_refresh_token.decode('utf-8'))
  86. b64_rflist.insert(12, self.getSalt(strLen=6))
  87. b64_rftoken = ''.join(b64_rflist)
  88. token = {'access_token': b64_atoken[::-1], 'refresh_token': b64_rftoken[::-1]}
  89. dictJSON = {'result_code': 0, 'reason': 'Success', 'result': token, 'error_code': 0}
  90. return json.dumps(dictJSON, ensure_ascii=False)
  91. else:
  92. return sqlJSON
  93. def verify_AToken(self, token, isAToken = True):
  94. if token == 'stest':
  95. self.accessDict['userID'] = '151547867345163613800138001'
  96. return 0
  97. if token == 'sformal':
  98. self.accessDict['userID'] = '151564262337939513800138001'
  99. return 0
  100. """
  101. :param token:
  102. :param isAToken:
  103. :return:
  104. """
  105. access_token = token[::-1]
  106. if len(access_token) < 18:
  107. return 303
  108. atoken = access_token[:12] + access_token[18:]
  109. print(atoken)
  110. try:
  111. token_str = base64.urlsafe_b64decode(atoken).decode('utf-8')
  112. except Exception as e:
  113. errorInfo = traceback.format_exc()
  114. print('base64 decode error: %s' % errorInfo)
  115. self.errormsg = 'base64 decode error: %s' % repr(e)
  116. return 304
  117. token_list = token_str.split('&')
  118. if len(token_list) != 2:
  119. return 303
  120. ts_str = token_list[0]
  121. jsonDict = json.loads(ts_str)
  122. print(jsonDict)
  123. userID = jsonDict.get('userID', None)
  124. mCode = jsonDict.get('mCode', None)
  125. if userID == None or mCode == None:
  126. return 303
  127. try:
  128. if isAToken:
  129. authToken = AuthToken_Token.objects.filter(tokenID_id=userID, access_token=atoken)
  130. else:
  131. authToken = AuthToken_Token.objects.filter(tokenID_id=userID, refresh_token=atoken)
  132. except Exception as e:
  133. errorInfo = traceback.format_exc()
  134. print('Database Query error: %s' % errorInfo)
  135. self.errormsg = 'Database Query error: %s' % repr(e)
  136. return 500
  137. if authToken:
  138. self.iCode = authToken[0].iCode
  139. hmac_token = token_list[1]
  140. hmac_at = hmac.new(ts_str.encode('utf-8'), self.iCode.encode('utf-8')).hexdigest()
  141. if hmac_at != hmac_token:
  142. return 306
  143. else:
  144. try:
  145. mCodeToken = AuthToken_Token.objects.filter(tokenID_id=userID)
  146. except Exception as e:
  147. errorInfo = traceback.format_exc()
  148. print('Database Query error: %s' % errorInfo)
  149. self.errormsg = 'Database Query error: %s' % repr(e)
  150. return 500
  151. if mCodeToken:
  152. '''
  153. if mCodeToken[0].mCode != mCode:
  154. return 313
  155. else:
  156. return 309
  157. '''
  158. pass
  159. else:
  160. return 309
  161. if isAToken:
  162. self.accessDict = jsonDict
  163. exp_at = jsonDict.get('exp_at', None)
  164. if exp_at == None:
  165. return 305
  166. if time.time() - float(exp_at) > 0:
  167. return 309
  168. else:
  169. self.refreshDict = jsonDict
  170. exp_rt = jsonDict.get('exp_rt', None)
  171. if exp_rt == None:
  172. return 305
  173. if time.time() - float(exp_rt) > 0:
  174. try:
  175. Device_User.objects.filter(userID = userID).update(online = False)
  176. except Exception as e:
  177. errorInfo = traceback.format_exc()
  178. print('Database Query error: %s' % errorInfo)
  179. self.errormsg = 'Database Query error: %s' % repr(e)
  180. return 500
  181. return 308
  182. try:
  183. device_user = Device_User.objects.get(userID=userID)
  184. device_user.online=True
  185. device_user.save()
  186. except Exception as e:
  187. pass
  188. return 0
  189. def refresh_AToken(self, Token):
  190. """
  191. :param Token:
  192. :return:
  193. """
  194. print('refresh_AToken')
  195. error_code = self.verify_AToken(token = Token, isAToken = False)
  196. if error_code == 0:
  197. refreshDict = self.refreshDict
  198. if refreshDict.get('exp_at', None) != None:
  199. exp_at = (datetime.utcnow() + EXPIRATION_DELTA).utctimetuple()
  200. refreshDict['exp_at'] = timegm(exp_at)
  201. refreshDict.pop('exp_rt')
  202. JSON = json.dumps(refreshDict, ensure_ascii=False)
  203. hmac_at = hmac.new(JSON.encode('utf-8'), self.iCode.encode('utf-8')).hexdigest()
  204. access_token = JSON + '&' + hmac_at
  205. b64_at = base64.urlsafe_b64encode(access_token.encode("utf-8"))
  206. userID = refreshDict.get('userID', None)
  207. tokenDict = {'access_token': b64_at.decode('utf-8')}
  208. tokenDict['tokenID_id'] = userID
  209. sqlJSON = SQLManager(content=tokenDict)
  210. sqlDict = json.loads(sqlJSON)
  211. error_code = sqlDict.get('error_code', None)
  212. if error_code != None and error_code == 0:
  213. b64_alist = list(b64_at.decode('utf-8'))
  214. b64_alist.insert(12, self.getSalt(strLen=6))
  215. b64_atoken = ''.join(b64_alist)
  216. token = {'access_token': b64_atoken[::-1], }
  217. dictJSON = {'result_code': 0, 'reason': 'Success', 'result': token, 'error_code': 0}
  218. return json.dumps(dictJSON, ensure_ascii=False)
  219. else:
  220. return sqlJSON
  221. else:
  222. return self.errorCodeInfo(error_code)
  223. def deToken(self,token):
  224. try:
  225. b64_alist = list(token)
  226. b64_alist.insert(12, self.getSalt(strLen=6))
  227. b64_atoken = ''.join(b64_alist)
  228. res_token = b64_atoken[::-1]
  229. code = self.verify_AToken(res_token)
  230. if code == 0:
  231. return res_token
  232. else:
  233. return False
  234. except Exception as e:
  235. return False
  236. def errorCodeInfo(self, error_code):
  237. print(error_code)
  238. return ResponseFormal(error_code)