Skip to content

Commit

Permalink
Add wechat support.
Browse files Browse the repository at this point in the history
  • Loading branch information
zxkane committed Jun 27, 2014
1 parent 8d0eb0d commit 25e80e8
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ Python Package For SNS sites with OAuth2 support

* 易于扩展 [参见doc.md](/doc.md)
* 统一的接口

* 各个站点,都有 `uid`, `name`, `avatar`, 属性

QQ 取回的 `avatar` 是40x40尺寸的,其余站点基本都是 48~50的尺寸

* 各个站点,都有统一的 `api_http_get``api_http_post` 接口

* 统一的错误处理

`api_http_get``api_http_post` 都可能引发异常,

应用程序只要 `try ... except SocialAPIError as e` 就能得到一致的错误信息:

* `e.site_name` 哪个站点发生错误
* `e.url` 发生错误是请求的url
* `e.api_error_msg` 由站点返回的错误信息 or urllib2 的错误信息
Expand All @@ -38,6 +38,7 @@ Python Package For SNS sites with OAuth2 support
* 百度
* 开心网
* 淘宝
* 微信


## Contributors
Expand Down Expand Up @@ -125,7 +126,7 @@ example中有个简单的session机制,
* 豆瓣文档太简陋
* 搜狐文档就是个渣!!! 都不想添加搜狐支持了
* 发现一些文档和实际操作有出入, 主要是文档里说的必要参数,不传也一样工作

* [腾讯][tocao_tencent_1] 文档里说取code的时候,state 必须 参数,但发现不传一样
* [搜狐][tocao_souhu_1] 和上面一样, wrap_client_state 参数

Expand Down
1 change: 1 addition & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Supported the following sites (and the list are growing):
* baidu (百度)
* kaixin001 (开心网)
* taobao (淘宝网)
* wechat (微信)



Expand Down
78 changes: 78 additions & 0 deletions socialoauth/sites/wechat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# -*- coding: utf-8 -*-
import re
import json
from urllib import quote_plus

from socialoauth.sites.base import OAuth2
from socialoauth.exception import SocialAPIError, SocialSitesConfigError


class Wechat(OAuth2):
AUTHORIZE_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize'
ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token'
OPENID_URL = 'https://api.weixin.qq.com/sns/userinfo'

SUPPORTED_SCOPES = ('snsapi_base', 'snsapi_userinfo')

@property
def authorize_url(self):
url = "%s?appid=%s&redirect_uri=%s&response_type=code" % (
self.AUTHORIZE_URL, self.CLIENT_ID, quote_plus(self.REDIRECT_URI)
)

if getattr(self, 'SCOPE', None) is not None:
if (self.SCOPE in self.SUPPORTED_SCOPES):
url = '%s&scope=%s' % (url, self.SCOPE)
else:
raise SocialSitesConfigError("SCOPE must be one of (%s)." %(','.join(self.SUPPORTED_SCOPES)), None)
else:
raise SocialSitesConfigError("SCOPE is required!", None)

url = url + '&state=socialoauth#wechat_redirect'
return url

def get_access_token(self, code):
data = {
'appid': self.CLIENT_ID,
'secret': self.CLIENT_SECRET,
'redirect_uri': self.REDIRECT_URI,
'code': code,
'grant_type': 'authorization_code'
}

res = self.http_get(self.ACCESS_TOKEN_URL, data, parse=False)
self.parse_token_response(res)

def build_api_url(self, url):
return url

def build_api_data(self, **kwargs):
data = {
'access_token': self.access_token,
'openid': self.uid
}
data.update(kwargs)
return data

def parse_token_response(self, res):
res = json.loads(res)

self.access_token = res['access_token']
self.expires_in = int(res['expires_in'])
self.refresh_token = res['refresh_token']

self.uid = res['openid']

if self.SCOPE == 'snsapi_userinfo':
res = self.api_call_get(self.OPENID_URL, lang='zh_CN')

if 'errcode' in res:
raise SocialAPIError(self.site_name, self.OPENID_URL, res)

self.name = res['nickname']
self.avatar = res['headimgurl']
self.avatar_large = res['headimgurl']
else:
self.name = ''
self.avatar = ''
self.avatar_large = ''

0 comments on commit 25e80e8

Please sign in to comment.