微信第三方登录

前戏

在使用微信作为我们的第三方登入软件之前,我们有必要去了解一下oauth2的原理,oauth2是一个给第三方授权的一个协议,通过这个协议,可以比较安全的将用户信息传递给第三方。微信的第三方登录就是基于oauth2完成的。

关于oauth2详细的我不在说明,具体的可以看我的另外一篇博客

具体使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
1.去微信的开放平台注册对应的网站应用,微信的开放平台的地址如下
https://open.weixin.qq.com/
ps:具体的注册流程这边也不详细说明,可以通过百度获得

2.注册成功后会获得一个对应的app_id以及secret_key将这两个记下。

3.通过设置前端的回调url,前端的流程走完后会获得到一个code,这个code传给后端后,我们就可以调用下述方法去获得对应的用户信息

class WXLogin2Register:
@staticmethod
def get_access_code(code: str):
"""
获取微信授权码
:param code:前端或app拉取的到临时授权码
:return:None 或 微信授权数据
"""

app_id = 'XXXXXX'
secret = 'XXXXXX'
try:
# 把查询条件转成url中形式
fields = parse.urlencode(
{"appid": app_id, "secret": secret,
"code": code, "grant_type": "authorization_code"}
)
# 拼接请求链接
url = 'https://api.weixin.qq.com/sns/oauth2/access_token?{}'.format(fields)

req = request.Request(url=url, method="GET")
# 请求数据,超时10s
res = request.urlopen(req, timeout=10)
# 解析数据
access_data = json.loads(res.read().decode())
print(access_data)
except Exception as e:
print(e)
return None

# 拉取微信授权成功返回
# {
# "access_token": "ACCESS_TOKEN", "expires_in": 7200,"refresh_token": "REFRESH_TOKEN",
# "openid": "OPENID","scope": "SCOPE"
# }

if "openid" in access_data:
return access_data

# 拉取微信授权失败
# {
# "errcode":40029,"errmsg":"invalid code"
# }
else:
return None

@staticmethod
def get_wx_user_info(access_data: dict):
"""
获取微信用户信息
:return:
"""
openid = access_data.get("openid")
access_token = access_data.get("access_token")
try:
# 把查询条件转成url中形式
fields = parse.urlencode({"access_token": access_token, "openid": openid})
# 拼接请求链接
url = 'https://api.weixin.qq.com/sns/userinfo?{}'.format(fields)
req = request.Request(url=url, method="GET")
# 请求数据,超时10s
res = request.urlopen(req, timeout=10)
# 解析数据
wx_user_info = json.loads(res.read().decode())
print(wx_user_info)
except Exception as e:
print(e)
return None

# 获取成功
# {
# "openid":"OPENID",
# "nickname":"NICKNAME",
# "sex":1,
# "province":"PROVINCE",
# "city":"CITY",
# "country":"COUNTRY",
# "headimgurl": "test.png",
# "privilege":[
# "PRIVILEGE1",
# "PRIVILEGE2"
# ],
# "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
#
# }
if "openid" in wx_user_info:
return wx_user_info
# 获取失败
# {"errcode":40003,"errmsg":"invalid openid"}
else:
return None

@staticmethod
def get_user_info(code: str) -> dict or bool:
"""调用上面两个方法直接获得wx用户信息"""
# 获取微信用户授权码
access_code = WXLogin2Register.get_access_code(code)
if not access_code:
return False
# 获取微信用户信息
wx_user_info = WXLogin2Register.get_wx_user_info(access_data=access_code)
if wx_user_info is None:
return False
else:
return wx_user_info