对接QQ登录前的准备工作
- 申请域名并通过备案,可通过阿里云和腾讯云等购买域名并备案,不建议使用中文域名
- 在qq互联中创建网站应用(https://connect.qq.com/index.html)
这就是中文域名备案所面临的窘境,官方不支持中文域名作为回调地址。
言归正传,准备工作做好后,最终目的就是为了拿到APP ID、APP Key和最终的回调地址。
django的配置文件中:
# QQ登陆相关配置信息
QQ_APP_ID = "实际的APP_ID"
QQ_APP_KEY = "实际的APP_KEY"
QQ_REDIRECT_URI = "http://注册的域名/oauth_callback.html"
实现qq登录,按照这几步即可,其实对接过程中只用了前四步,即获取到用户的open_id为止:
- 获取登录的跳转地址
- 用户授权后获取Authorization Code
- 通过Authorization Code获取Access Token
- 获取用户的open_id
- 访问/修改用户的基本信息
实现qq登录的工具类
from urllib.parse import urlencode,parse_qs
from urllib.request import urlopen
from django.conf import settings
import json
from .exceptions import QQAPIError
class OAuthQQ():
"""
QQ第三方登陆工具类
这里保存的是QQ第三方登陆需要使用操作方法和数据
"""
def __init__(self):
self.app_id = settings.QQ_APP_ID
self.app_key = settings.QQ_APP_KEY
self.redirect_uri = settings.QQ_REDIRECT_URI
def generate_qq_login_url(self,state):
"""
生成QQ登陆的url地址
:param state: QQ登陆成功以后需要跳转的用户页面
:return: QQ登陆地址
"""
base_url = "https://graph.qq.com/oauth2.0/authorize" + "?"
query_params = {
"response_type":"code", # 固定值
"client_id": self.app_id, # app id
"redirect_uri":self.redirect_uri,
"state": state, # 登陆页面中的跳转地址
"scope":"get_user_info", # 声明使用的接口名称,可选
}
# 把字典转换成查询字符串
# https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id
query_string = urlencode(query_params)
url = base_url + query_string
return url
def get_qq_access_token(self,code):
"""凭借code发起请求到QQ服务器获取access_token"""
# 拼接接口地址和参数
base_url = "https://graph.qq.com/oauth2.0/token" + "?"
query_params = {
"grant_type": "authorization_code",
"client_id": self.app_id,
"client_secret": self.app_key,
"code": code,
"redirect_uri": self.redirect_uri,
}
# 把字典转换成查询字符串
query_string = urlencode(query_params)
url = base_url + query_string
# 发起请求
response = urlopen(url)
response_data = response.read().decode()
# 把查询字符串转换成字典
data = parse_qs(response_data)
access_token = data.get('access_token')
if not access_token:
raise QQAPIError
# 返回access_token
return access_token[0]
def get_qq_openid(self,access_token):
"""凭借access_token发起请求到QQ服务器获取openid凭借access_token发起请求到QQ服务器获取openid"""
url = "https://graph.qq.com/oauth2.0/me?access_token=" + access_token
# 发起请求
response = urlopen(url)
response_data = response.read().decode()
try:
data = json.loads( response_data[10:-4] )
except:
raise QQAPIError
else:
return data["openid"]
围绕上述的工具类讲述qq登录四步的具体实现,主要有两个接口,一个就是获取qq登录跳转url,另外一个就是实现登录(获取open_id)的接口。
接口一:利用OAuthQQ工具类中的generate_qq_login_url方法生成登录的跳转链接,实现qq登录的第一步。前端点击qq登录的图标,请求该接口,获取登录链接,跳转到如下页面进行授权登录。
用户授权登录后会返回 http://注册的域名/oauth_callback.html?code=9A5F************************06AF&state=test类似的链接,code是qq客户端返回的,也就是 qq登录第二步。
接口二:利用OAuthQQ工具类中的get_qq_access_token方法获取access_token,通过get_qq_openid方法再去获取openid。这个接口实现了qq登录的第三步和第四步。
# 接口二关键代码
try:
# 凭借code发起请求到QQ服务器获取access_token
access_token = oauth_qq.get_qq_access_token(code)
# 凭借access_token发起请求到QQ服务器获取openid
openid = oauth_qq.get_qq_openid(access_token)
except QQAPIError:
return Response({"message": "QQ服务异常"}, status=status.HTTP_503_SERVICE_UNAVAILABLE)
最后将获取的openid与用户进行绑定即实现最终的用户登录。