django-allauth有很多第三方登录的集成确没有qq第三方登录,是因为qq的第三方登录需要用access_token获取openid后才能继续获取用户信息,比其他平台多了一步,具体可以看我写的QQ第三方登录流程。
首先在allauth的目录...\allauth\socialaccount\providers\
下面新建qq文件夹,创建provider.py、urls.py、views.py文件
########provider.py#########
from allauth.socialaccount.providers.base import ProviderAccount
from allauth.socialaccount.providers.oauth2.provider import OAuth2Provider
class QQAccount(ProviderAccount):
def get_profile_url(self):
return 'https://graph.qq.com/user/get_user_info'
def get_avatar_url(self):
return self.account.extra_data.get('figureurl_qq_2')
def to_str(self):
default = super(QQAccount, self).to_str()
return self.account.extra_data.get('nickname', default)
class QQProvider(OAuth2Provider):
id = 'qq'
name = 'QQ'
account_class = QQAccount
def extract_uid(self, data):
return data['openid']
def extract_common_fields(self, data):
return dict(username='qq用户_'+data.get('nickname'),
name=data.get('name'))
provider_classes = [QQProvider]
########urls.py###########
from django.conf.urls import include, url
from allauth.utils import import_attribute
from .provider import QQProvider
def qq_urlpatterns(provider):
login_view = import_attribute(
provider.get_package() + '.views.oauth2_login')
callback_view = import_attribute(
provider.get_package() + '.views.oauth2_callback')
urlpatterns = [
url(r'^login/$',
login_view, name=provider.id + "_login"),
# qq的回调链接验证十分严格,不能有斜线结尾,因此需要修改
url(r'^login/callback$',
callback_view, name=provider.id + "_callback"),
]
return [url('^' + provider.get_slug() + '/', include(urlpatterns))]
urlpatterns = qq_urlpatterns(QQProvider)
#########views.py#############
import requests, re, json
from allauth.socialaccount.providers.oauth2.views import (
OAuth2Adapter,
OAuth2CallbackView,
OAuth2LoginView,
)
from .provider import QQProvider
class QQOAuth2Adapter(OAuth2Adapter):
provider_id = QQProvider.id
authorize_url = 'https://graph.qq.com/oauth2.0/authorize'
access_token_url = 'https://graph.qq.com/oauth2.0/token'
open_id_url = 'https://graph.qq.com/oauth2.0/me'
profile_url = 'https://graph.qq.com/user/get_user_info'
def complete_login(self, request, app, token, **kwargs):
open_id_resp = requests.get(self.open_id_url, params={'access_token': token.token})
# 返回的是jsonp需要解析一下 'callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} )';
open_id_dict = json.loads(re.match(r'callback\( ({.*}) \);', open_id_resp.text).group(1))
openid = open_id_dict.get('openid')
oauth_consumer_key = open_id_dict.get('client_id')
resp = requests.get(self.profile_url,
params={'access_token': token.token,
'oauth_consumer_key': oauth_consumer_key,
'openid': openid})
extra_data = resp.json()
# 使用openid作为uid
extra_data['openid'] = openid
return self.get_provider().sociallogin_from_response(request, extra_data)
oauth2_login = OAuth2LoginView.adapter_view(QQOAuth2Adapter)
oauth2_callback = OAuth2CallbackView.adapter_view(QQOAuth2Adapter)