[Python-modules-commits] [python-social-auth] 13/131: Add weixin public number oauth backend.

Wolfgang Borgert debacle at moszumanska.debian.org
Sat Dec 24 15:16:56 UTC 2016


This is an automated email from the git hooks/post-receive script.

debacle pushed a commit to tag v0.2.20
in repository python-social-auth.

commit 24661a7409828f6d158dabfb81c7247686e14325
Author: duoduo369 <duoduo3369 at gmail.com>
Date:   Tue Apr 5 14:49:25 2016 +0800

    Add weixin public number oauth backend.
    
    Weixin have two oauth method:
    1. User login with web, when user scan 2D barcode;
    2. User click green submit button in Weixin app.
    
    These two way are very different in development scene.
    Beacause my poorly english and developer who use weixin oauth
    almost are Chinese.I'll explain in Chinese.
    
    微信有两种授权方式:
    1. 通过微信开放平台注册的账号,用户可以在web上点击用微信登陆,此时微信
    会生成二维码,用户扫描后即可登陆;
    2. 通过微信app登陆,开发者在微信开放平台注册微信公众号(服务号)后,用户
    打开需要授权的页面后会先出现一个有绿色确认按钮的页面,当用户点击登陆后
    完成登陆逻辑.
    
    注意
    1. 如果你是在两个平台注册的账号,用户体系需要用微信的uninionid自己
    做唯一性关联,因为微信认为这是两个app即使你用同一个开放者账号注册;所以
    现象是同一个用户用微信打开两个不同场景的服务登陆时,openid是不同的,但是
    可以通过uninionid来关联,唯一确认用户。
    2. 微信app的登陆方式请添加一个可以按照日期或者其他任何随机变化的参数,
    因为微信对于转发有奇怪的限制,当转发量到一定程度后,微信会废弃这个链接,
    现象是你自己在朋友圈可以看到自己转发的链接,但是你的朋友们却看不到。
---
 social/backends/weixin.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/social/backends/weixin.py b/social/backends/weixin.py
index 1b5c2d5..0eb81e5 100644
--- a/social/backends/weixin.py
+++ b/social/backends/weixin.py
@@ -3,6 +3,7 @@
 """
 Weixin OAuth2 backend
 """
+import urllib
 from requests import HTTPError
 
 from social.backends.oauth import BaseOAuth2
@@ -99,3 +100,74 @@ class WeixinOAuth2(BaseOAuth2):
         self.process_error(response)
         return self.do_auth(response['access_token'], response=response,
                             *args, **kwargs)
+
+
+class WeixinOAuth2APP(WeixinOAuth2):
+    """Weixin OAuth authentication backend
+
+        can't use in web, only in weixin app
+    """
+    name = 'weixinapp'
+    ID_KEY = 'openid'
+    AUTHORIZATION_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize'
+    ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token'
+    ACCESS_TOKEN_METHOD = 'POST'
+    REDIRECT_STATE = False
+
+    def auth_url(self):
+        if self.STATE_PARAMETER or self.REDIRECT_STATE:
+            # Store state in session for further request validation. The state
+            # value is passed as state parameter (as specified in OAuth2 spec),
+            # but also added to redirect, that way we can still verify the
+            # request if the provider doesn't implement the state parameter.
+            # Reuse token if any.
+            name = self.name + '_state'
+            state = self.strategy.session_get(name)
+            if state is None:
+                state = self.state_token()
+                self.strategy.session_set(name, state)
+        else:
+            state = None
+
+        params = self.auth_params(state)
+        params.update(self.get_scope_argument())
+        params.update(self.auth_extra_arguments())
+        params = urllib.urlencode(sorted(params.items()))
+        return '{}#wechat_redirect'.format(self.AUTHORIZATION_URL + '?' + params)
+
+
+    def auth_complete_params(self, state=None):
+            appid, secret = self.get_key_and_secret()
+            return {
+                'grant_type': 'authorization_code',  # request auth code
+                'code': self.data.get('code', ''),  # server response code
+                'appid': appid,
+                'secret': secret,
+            }
+
+    def validate_state(self):
+        return None
+
+    def auth_complete(self, *args, **kwargs):
+        """Completes loging process, must return user instance"""
+        self.process_error(self.data)
+        try:
+            response = self.request_access_token(
+                self.ACCESS_TOKEN_URL,
+                data=self.auth_complete_params(self.validate_state()),
+                headers=self.auth_headers(),
+                method=self.ACCESS_TOKEN_METHOD
+            )
+        except HTTPError as err:
+            if err.response.status_code == 400:
+                raise AuthCanceled(self)
+            else:
+                raise
+        except KeyError:
+            raise AuthUnknownError(self)
+
+        if 'errcode' in response:
+            raise AuthCanceled(self)
+        self.process_error(response)
+        return self.do_auth(response['access_token'], response=response,
+                            *args, **kwargs)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-social-auth.git



More information about the Python-modules-commits mailing list