一、开发环境

django 1.10.2

python3.5.2

django-social-auth 0.3.6

二、申请QQ互联 APPID及SECRECT_KEY

大致步骤:

1.成为QQ互联开发者

2.创建应用

3.获取应用app_id 及secret_key

三、代码

1.安装认证框架

$ pip3 install social-auth-app-django

2.在INSTALLED_APPS中添加应用(settings.py)

INSTALLED_APPS = (...'social_django',...
)

3.更新数据库

python3 managy.py migrate

4.在认证后端添加QQ认证以及QQ互联的key和id(settings.py)

AUTHENTICATION_BACKENDS = (...'social_core.backends.qq.QQOAuth2',
)
SOCIAL_AUTH_QQ_KEY = 'your qq app id,like some number,for examle 230402020' # QQ APP_ID
SOCIAL_AUTH_QQ_SECRET = 'you qq seckey ,combined by letter with number,for examle: f123bas324' # QQ SECRECT_KEY
SOCIAL_AUTH_QQ_USE_OPENID_AS_USERNAME = True

5.添加根urls.py的URL路由

urlpatterns = [......url('', include('social_django.urls', namespace='social'))
]

6.在需要登录的地方加上如下代码:

<a href="{% url "social:begin" "qq" %}">QQ登录 <!-- 这个登录标识注意要满足QQ互联的要求 --></a>

7.settings.py中的TEMPALTES如下:

TEMPLATES = [{...'OPTIONS': {...'context_processors': [...'social_django.context_processors.backends','social_django.context_processors.login_redirect',...]}}
]

四、可能出现的问题

1.认证页面是空白页面

解决方案,检查APPID和SECRET_KEY是否填写正确

2.redirect_url不合法 10010

解决方案,注意域名的一致性,此问题是由于http请求中url和QQ互联中的 回调地址不同引起的,

https://graph.qq.com/oauth/show?which=Login&display=pc&redirect_uri=http://localhost.com:8080/complete/qq/&client_id=xxxx&response_type=code&state=xxxx

在实际使用过程中出现同样问题,主要是因为网站使用了多个域名,使用www.czxxs.cn和czxxs.cn都能访问网站,此时可以把回调地址设置为两个地址,如下:

再次尝试,错误消失

3.用openid代替昵称存储在数据库,在settings.py中加上以下语句(避免QQ昵称相同引起用户存储错误)

SOCIAL_AUTH_QQ_USE_OPENID_AS_USERNAME = True

参考连接:http://python-social-auth.readthedocs.io/en/latest/configuration/django.html

http://python-social-auth.readthedocs.io/en/latest/backends/qq.html

备注:

功能可以根据上面两个连接进行完善,有问题欢迎留言

五、扩展(Pipeline管道),实现认证流程的自定义

用途:在认证过程中,可以加入自己的函数,实现认证过程的定制化。

原理:自定义的函数会收到当前进程传递的参数,包括strategy,user,和request,建议在定义函数的时候额外添加**kwargs参数来避免 未知参数错误。

返回:管道(自定义的函数)可以返回dict或者None,如果返回其他内容,这些内容则会被看做 一个  response,然后会直接返回给客户端,Partial Pipeline会介绍原理)

如果返回的dict,那么dict的值会合并到 kwargs参数中,然后传递给下一个pipeline,如果返回None将被看做返回了'{}'空的字典

(认证管道)Authentication Pipeline

认证流程的最后一步,是处理一系列可操作的管道,可以在管道中添加自定义的功能,也可以删除默认的管道。认证系统默认的管道是创建用户实例,然后从认证服务商处获取一些基本的信息。默认的管道如下:

(# 从服务商获取用户信息,然后以一种简单的格式返回,用来将来创建用户使用# 有时候用户的信息已经在认证消息的 Response 响应中了,但是有时需要使用服务商提供的api'social_core.pipeline.social_auth.social_details',# 从服务商处获取 social uid,这个uid是服务商给用户的唯一标识'social_core.pipeline.social_auth.social_uid',# 验证当前认证流程是否合法,需要提供邮箱和域名白名单(好像没用到过,可以自己深入研究)'social_core.pipeline.social_auth.auth_allowed',# 判断当前认证账户是否已经关联到了网站用户、'social_core.pipeline.social_auth.social_user',# 为认证用户创建一个用户名,如果用户名冲突则在用户名后添加随机字符串'social_core.pipeline.user.get_username',# 给用户发送验证邮件,验证其邮箱的真实性,默认禁用# 'social_core.pipeline.mail.mail_validation',# 把 当前社交认证信息和其他 邮箱相似的用户关联起来,默认禁用# 'social_core.pipeline.social_auth.associate_by_email',#如果没有发现用户账户则创建用户(以social user的信息创建)'social_core.pipeline.user.create_user',#创建将社交帐户与用户关联的记录。'social_core.pipeline.social_auth.associate_user',#使用settings.py指定的值(和access_token等默认值)填充社交记录中的extra_data字段。'social_core.pipeline.social_auth.load_extra_data',#使用来自auth服务的任何更改的信息更新用户记录。'social_core.pipeline.user.user_details',
)

可以在setting中通过设置SOCIAL_AUTH_PIPELINE来覆盖默认的管道。例如可以通过设置如下变量来达到,
不创建用户,只与已经存在的用户关联的目的。

SOCIAL_AUTH_PIPELINE = ('social_core.pipeline.social_auth.social_details','social_core.pipeline.social_auth.social_uid','social_core.pipeline.social_auth.auth_allowed','social_core.pipeline.social_auth.social_user','social_core.pipeline.social_auth.associate_user','social_core.pipeline.social_auth.load_extra_data','social_core.pipeline.user.user_details',
)

这是在用户已经授权的情况下可以通过这种方式来关联用户,因此在dict中会有 user这一键值。如果认证完全来自外部,必须提供一个用来产生 user键值的管道,比如:

SOCIAL_AUTH_PIPELINE = ('social_core.pipeline.social_auth.social_details','social_core.pipeline.social_auth.social_uid','social_core.pipeline.social_auth.auth_allowed','myapp.pipeline.load_user','social_core.pipeline.social_auth.social_user','social_core.pipeline.social_auth.associate_user','social_core.pipeline.social_auth.load_extra_data','social_core.pipeline.user.user_details',
)

也可以在setting中为每一个后端定制管道,例如 SOCIAL_AUTH_TWITTER_PIPELINE,指定的pipeline会覆盖默认的pipeline。

每个pipeline函数会收到以下参数:

1.strategy(包含访问当前存储,后端和请求的参数)

2.社交认证端给出的userid

3.社交认证端给出的用户信息

4.is_new标志,默认值为False

5.传递给 auth_complete方法的参数,默认的视图传递以下参数:

①当前登录的用户,如果未登录,是None

②当前的request

Disconnection Pipeline(断开管道)

和认证管道想反,当用户断开社交账户关联时的功能。

比如,当用户断开所有社交账户关联时,需要用户填写登录密码(这种情况是针对,在认证管道中直接创建用户的情况,认证管道中存在'social_core.pipeline.user.create_user' 这条语句时才需要考虑断开管道,因为这个管道会直接用用户的社交 user_id创建用户名,但是却可以不存在密码如下图)。

可以通过覆盖默认的断开管道,然后添加一个可以检查用户是否有密码的函数,如果不存在的话重定向到填写密码表单,然后继续执行断开流程。注意断开连接需要确保在POST方法下进行,一个简单的方法来确保这一点,是使您的表单POST到/ disconnect /并在管道功能中设置需要密码。

覆盖断开管道的设置如下:

SOCIAL_AUTH_DISCONNECT_PIPELINE = (# 验证社交关联是否可以断开(确保用户登录不会被断开 破坏?(compromised))'social_core.pipeline.disconnect.allowed_to_disconnect',# 收集需要断开的关联'social_core.pipeline.disconnect.get_entries',# 抽取acces_token'social_core.pipeline.disconnect.revoke_tokens',# 移除关联'social_core.pipeline.disconnect.disconnect',
)

同样也可以设置针对性管道如: SOCIAL_AUTH_TIWTTER_DISCONNECT_PIPELINE.

Partial Pipeline(部分?管道)

可以暂停管道返回到用户需要执行的动作,然后再继续执行。

为了实现这一装饰器功能,需要用 @partial装饰器断开处理流程,partial装饰器文件位置位于social/pipeline/partial.py

当需要返回到处理流程时,只需要把用户重定向到/complete/<backend>/或者/diconnect/<backend>/视图中,这样管道就会继续执行同样的功能,但是也可以中断处理流程。

@partial把需要的数据存储到数据库中名为social_auth_partial的表中。 此表包含着可以在将来从任何浏览器恢复的信息,同时会删除浏览器会话的旧依赖关系,从而防止浏览器之间的复制行为。

partial数据根据UUID token来区分,token可以存储在session或者追加在url中以partial_token参数命名(默认值),库会从request中获取这些值,然后加载需要的值来让用户继续执行流程。

pipeline功能函数会得到一个current_partial的实例,包含partial token和数据库中需要的数据。

为了使后端可以重定向到任何社交视图,只需要:

backend = current_partial.backend

通过下列语句可以覆盖默认的参数名称:

SOCIAL_AUTH_PARTIAL_PIPELINE_TOKEN_NAME = '...

示例:

https://github.com/python-social-auth/social-examples

Extending the Pipeline(扩展管道)

扩展一个管道需要:

1.编写功能函数

2.把功能函数放到可引用的地方

3.用新管道覆盖默认的管道

写功能时比较简单,但是需要注意的是,管道功能的排列顺序会影响到认证流程,因此需要谨慎安排。pipeline的位置会决定每个管道会收到什么参数,比如,把你自定义的功能管道放到social_core.pipeline.user.create_user可以确保你的功能得到一个用户实例(创建的或者是已经存在的)而不是None。pipeline管道功能函数会收到需要参数,包含使用的后端,不同的模型实例,服务器request和社交提供商的response,简单介绍如下:

strategy:当前strategy实例

backend:当前backend实例

uid:社交服务商提供的uid,这个uid是当前用户在社交服务商处的唯一标识。

response:{}或者object()

服务器user-details response,取决于使用的协议(),通常是一个包含用户个人信息详情的dict,这已经包含了许多的用户详情,有时scope会增加信息的总量

details = {}
后端产生的用户的基本信息,用来去创建或者更新user model(字典中包含username,email.first_name,last_name 和fullname等值)
user = None
user实例,如果没有创建用户或者在数据库中没有找到则是None
social = None
给出用户已关联的社交认证,如果用户没有创建或者数据库中不存在则返回None

通常自定义管道功能函数时,只需要从response中获得一些参数,但是你可以通过调用其他api去获取更多用户信息,然后存储到其他地方。

下面是一个创建用户Profile实例的一个例子,profile实例存储的是一些社交服务商返回的信息,(如Facebook,Facebook的response通常如下)

{'username': 'foobar','access_token': 'CAAD...','first_name': 'Foo','last_name': 'Bar','verified': True,'name': 'Foo Bar','locale': 'en_US','gender': 'male','expires': '5183999','email': 'foo@bar.com','updated_time': '2014-01-14T15:58:35+0000','link': 'https://www.facebook.com/foobar','timezone': -3,'id': '100000126636010',
}

假如我们想存储用户的个人简介链接,性别和时区到数据库,则功能管道可以如下:

def save_profile(backend, user, response, *args, **kwargs):if backend.name == 'facebook':profile = user.get_profile()if profile is None:profile = Profile(user_id=user.id)profile.gender = response.get('gender')profile.link = response.get('link')profile.timezone = response.get('timezone')profile.save()

现在我们只需要让soical-auth使用我们的管道即可,因为这个管道需要user实例,我们需要把他放到social_core.pipeline.user.create_user之后,可以确保有一个用户。

SOCIAL_AUTH_PIPELINE = ('social_core.pipeline.social_auth.social_details','social_core.pipeline.social_auth.social_uid','social_core.pipeline.social_auth.auth_allowed','social_core.pipeline.social_auth.social_user','social_core.pipeline.user.get_username','social_core.pipeline.user.create_user','path.to.save_profile',  # <--- set the path to the function'social_core.pipeline.social_auth.associate_user','social_core.pipeline.social_auth.load_extra_data','social_core.pipeline.user.user_details',
)

目前我们创建的管道功能函数返回时None,即被看做返回的是{},如果你想要profile能在下个管道中使用,那你只需要返回{'profile':profile}.

六、异常处理

在认证过程中会产生许多异常,需要处理,此时可以利用django Middleware来解决。

django social auth提供了一个基础中间件,通过Django消息框架向用户提供消息,然后通过重定向到一个中间件方法中定义的URL来处理SocialAuthBaseException。

中间件在social_django.middleware.SocialAuthExceptionMiddleware。 其中的任何方法都可以被覆盖,但为了简单起见,建议使用这两种方法:

get_message(request, exception)
get_redirect_uri(request, exception)

默认情况下,消息是异常消息,重定向的URL是由LOGIN_ERROR_URL设置指定的位置。

如果'strategy()'装饰器检测到有效的后端,则它将在request.strategy.backend中可用,并且process_exception()将使用它来构建后端相关的重定向URL,但如果未定义,则将其回退到默认值。

如果下列设置中,任意一项被定义为True,那么异常处理都是不能够使用:

<backend name>_SOCIAL_AUTH_RAISE_EXCEPTIONS = True
SOCIAL_AUTH_RAISE_EXCEPTIONS = True
RAISE_EXCEPTIONS = True
DEBUG = True

重定向的目的会得到两个参数:

message = ''
来自触发异常处的消息,在某些情况下,它是在验证过程中由社交运营商返回的消息
Message from the exception raised, in some cases it’s the message returnedby the provider during the auth process.
backend = ''
正在使用的后端(backend),前提是合法的后端

中间件将尝试使用Django内置消息应用程序来存储异常消息,并使用社会认证和后端名称进行标记。 如果应用程序未启用或发生MessageFailure错误,则应用程序将默认为上述URLformat。

django QQ认证登录相关推荐

  1. Django对接第三方认证登录平台(QQ登录)

    QQ登录开发文档 QQ互联开发者申请步骤 若想实现QQ登录,需要成为QQ互联的开发者,审核通过才可实现. 相关链接: http://wiki.connect.qq.com/%E6%88%90%E4%B ...

  2. python Django QQ第三方登陆认证

    QQ登录开发文档 QQ登录:即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 1. QQ互联开发者申请步骤 若想实现QQ登录,需要成为QQ互联的开发者 ...

  3. 【django】用户登录模块实现步骤(一)之QQ登录模型类【32】

    一.QQ登录流程分析 二.户登录 QQ登录成功后,我们需要将QQ户和芒果头条户关联到起,便下次QQ登录时使,所以我们选择使MySQL数据库进存储. 1.定义QQ登录模型类 创建个新的应oauth,来实 ...

  4. QQ第三方登录认证流程

    一.注册成为QQ开发者 1.进入注册网站:https://connect.qq.com/index.html 2.登录QQ号,点击头像进入认证页面 3.选择"个人开发者",并如实填 ...

  5. Python Django进阶教程(五)(session,Django用户认证)

    Django版本:1.11 操作系统:Windows Python:3.5 欢迎加入学习交流QQ群:657341423 session(会话),Django用户认证. 每个网站都cookies,会话, ...

  6. python调用qq互联_Django项目中实现使用qq第三方登录功能

    使用qq登录的前提是已经在qq互联官网创建网站应用并获取到QQ互联中网站应用的APP ID和APP KEY 1,建路由 # qq登录 path('loginQq/',qq.loginQq,name=' ...

  7. 快速接入 GitHub、QQ 第三方登录方式

    点击上方 好好学java ,选择 星标 公众号重磅资讯,干货,第一时间送达 今日推荐:推荐 19 个 github 超牛逼项目!个人原创100W +访问量博客:点击前往,查看更多 本文提及第三方登录涉 ...

  8. drcom宽带认证登录超时_开发SSO单点登录需要注意的问题

    一.单点登录系统开发需要注意的问题 1.单点登录系统需要支持jsonp请求? 单点登录系统主要是向其他系统提供用户身份验证服务,因此需要提供对外接口,而外部系统通过接口访问时,必然涉及跨域问题,因此需 ...

  9. 【Django】认证系统

    目录 #. auth模块 1. 认证 authenticate() 2. 登陆 login(HttpRequest, user) 3. 注销 logout(request) 4. 认证判断 is_au ...

最新文章

  1. mysql 交集_MYSQL交集函数
  2. LeetCode 537. 复数乘法
  3. html响应式布局_媒体查询
  4. SpringMVC 配置注解的映射器、适配器(重点)
  5. Python花式编程案例锦集(2)
  6. ORA-00018-超出最大连接数
  7. 用pygame实现打飞机游戏-2-检测键盘
  8. 海量数据和高并发下的 Redis 业务优化实践
  9. springboot二手交易平台 毕业设计-附源码290915
  10. BD NetDisk不限速下载,某度网盘不限速下载,跑满带宽,网盘下载器,网盘高速下载器,不限速网盘下载,AntNetDiskDownloader
  11. 数据库中update怎么用事例_Oracle的update语句set里使用子查询的例子解释
  12. android优化最强软件,手机提速谁最行?十款安卓优化软件比拼
  13. 千万千万不可运行的 Linux 命令
  14. 一个人怎么做好社群的日常高效管理?
  15. 桌面不显示我的计算机显示器,电脑桌面显示怎么分屏显示不出来怎么办
  16. mysql和myODBC安装和配置
  17. 2022年模式识别高峰论坛学习笔记
  18. Aspect Joinpoint Advice Pointcut 区别
  19. CCM5.0 应用实例(SIP X-lite)
  20. Linux 是洗衣粉 关于Linux 的10个趣事

热门文章

  1. android ntfs u盘,NTFS让U盘短命?想多了
  2. mt4量化交易接口:分享日常量化选股方法
  3. 某人将1000元存入银行 某公司需用一台设备 某企业为了建一项目 建设期3年,共贷款700万元
  4. 海面电磁散射MATLAB程序,matlab 电磁散射特性计算
  5. “rm -rf /” 与 “rm -rf /*”的强大威力,瘫痪系统,推荐使用mv代替rm
  6. 【原创】ubuntu下收听香港电台和其他电台
  7. BIOS怎么开启UEFI模式|电脑设置UEFI启动的方法
  8. dos 查看wifi 密码命令
  9. 毕业设计-基于微信小程序的“掌上实验室” 安全教育与管理系统
  10. 手机python3.0编程软件-怎么用手机编写Python程序?