unionpay.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import logging
  4. import urllib
  5. from apilib.systypes import IterConstant
  6. from apps.web.core.auth.base import AuthBridge
  7. from apps.web.user.conf import USER_AUTH_REDIRECT_URL
  8. from library.unionpay.oauth import UnionPayOAuth
  9. from apilib.utils_url import add_query
  10. logger = logging.getLogger(__name__)
  11. class unionAuthScope(IterConstant):
  12. # 静默跳转,无需用户点击授权
  13. AUTH_SCOPE_BASE = 'upapi_base'
  14. class UnionAuthBridge(AuthBridge):
  15. TOKEN_CACHE_KEY = 'access_token_from_{appid}_{code}'
  16. # 测试网关oauth
  17. DEV_ALIPAY_OAUTH_URL = \
  18. 'https://open.95516.com/s/open/html/oauth.html?' + \
  19. 'appId={appid}&scope={scope}&redirectUri={encoded_return_uri}&state={state}&responseType=code'
  20. # 生产环境网关oauth
  21. #https://open.95516.com/s/open/html/oauth.html?appId=APPID&redirectUri=REDIRECTURI&responseType=code&scope=SCOPE&state=STATE
  22. PRODUCTION_ALIPAY_OAUTH_URL = \
  23. 'https://open.95516.com/s/open/html/oauth.html?' + \
  24. 'appId={appid}&scope={scope}&redirectUri={encoded_return_uri}&state={state}&responseType=code'
  25. def __init__(self, app):
  26. self.app = app
  27. if self.debug:
  28. self._auth_gateway_tmpl = self.DEV_ALIPAY_OAUTH_URL
  29. else:
  30. self._auth_gateway_tmpl = self.PRODUCTION_ALIPAY_OAUTH_URL
  31. def __repr__(self):
  32. return '<unionAuthBridge(appid=%s, secret=******, occupant=%s)>' \
  33. % (self.app.appid, self.app.occupantId)
  34. @property
  35. def appid(self):
  36. return self.app.appid
  37. @property
  38. def secret(self):
  39. return self.app.secret
  40. @property
  41. def occupantId(self):
  42. return self.app.occupantId
  43. @property
  44. def enable(self):
  45. return self.app.alipay_enable
  46. @property
  47. def client(self):
  48. return UnionPayOAuth(self.appid, self.secret)
  49. def authorize(self, auth_code):
  50. logger.debug('{} authorize enter. code = {}'.format(repr(self), auth_code))
  51. if auth_code is None:
  52. logger.error('{} fail to authorize because code is null'.format(repr(self)))
  53. return None
  54. try:
  55. openId = self.client.get_oauth_token(auth_code).get('openid')
  56. logger.debug('{} success to authorize. open id = {}'.format(repr(self), openId))
  57. return openId
  58. except Exception as e:
  59. logger.error('{} fail to authorize because of exception. code = {}'.format(repr(self), auth_code))
  60. logger.exception(e)
  61. return None
  62. def get_user_info(self, token,code):
  63. # type:(str)->dict
  64. logger.debug('{bridge} get user info. code = {code}'.format(bridge = repr(self), code = code))
  65. return self.client.get_user_info(token = token, code = code)
  66. def generate_auth_url(self, redirect_uri, payload = '', scope = unionAuthScope.AUTH_SCOPE_BASE):
  67. """
  68. 生成授权url
  69. :param redirect_uri:
  70. :param payload:
  71. :param scope:
  72. :return:
  73. """
  74. redirect_uri = ''
  75. return UnionPayOAuth(self.appid, self.secret, scope = scope).authorize_url(redirect_uri = redirect_uri)
  76. def generate_auth_callback_url(self, payload = None, auth_callback_url = USER_AUTH_REDIRECT_URL.UNIONPAY):
  77. """
  78. 生成微信跳转url base范围,只能获取openId
  79. :param payload:
  80. :return:
  81. """
  82. logger.debug('generate_auth_callback_url enter. bridge = {}, callback url = {}; payload = {}'.format(repr(self),
  83. auth_callback_url,
  84. payload))
  85. if payload:
  86. callback_url = add_query(auth_callback_url, {'payload': payload})
  87. encoded_return_uri = urllib.quote_plus(callback_url)
  88. result = self._auth_gateway_tmpl.format(appid = self.appid,
  89. scope = unionAuthScope.AUTH_SCOPE_BASE,
  90. encoded_return_uri = encoded_return_uri,
  91. state = '')
  92. logger.debug('generate_auth_callback_url success. result = {}'.format(str(result)))
  93. return result