对于现在的网站来说,第三方登陆可以说是一个常用的设计了,通过授权来实现诸如qq,微信,微博等第三方平台的第三方登陆。而对于Django的drf来说,也是可以很好的嵌入第三方登陆模块的。
第三方登录都是采用OAuth2.0规范来实现的,基本流程是:
1、注册相关平台的开放平台的开发者账号,从而可以新建应用来开发调试。比如说微博就是在微博开放平台;微信就是在微信开放平台,QQ就是在QQ互联。
2、注册完账号后就可以在相关平台注册应用了。注册应用会得到appkey和appsecrt,这是必要的两个参数,以qq为例:
- (1)、第一步是获取Authorization Code,通过访问文档定义的接口,传递相关必要参数如appkey和appsectrt参数,拼接参数至url,用get方式访问url。
- (2)、第二步是会跳转至第三方登陆页面,输入账号密码登陆成功后,会重定向至预设的redirect_url,并传递回Authorization Code
- (2)、第三步是用Authorization Code获取到Access Token,当页面重定向至设定的重定向url后(通常是网站首页),即可以调用某个接口访问第三方的接口,拼接url传入Authorization Code获取到Access Token,通过Access Token可以获取到用户信息,随后进行注册等操作。
drf实现第三方登录可以使用现成的框架,如github上的social—app—django,http://python-social-auth.readthedocs.io/en/latest/。
一般设置步骤是:
- 安装框架
pip install social-auth-app-django,安装的时候会附带安装一些依赖,比如social-core等,而框架也是基于social- core开发的。 在settings的INSTALLED_APPS中注册
INSTALLED_APPS = [ 。。。。。 social_django, ]
在setting文件的DATABASES中设置数据库引擎,因为第三方登录需要的是innodb,这样做后面的migration才不会出错。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': "mxshop", 'USER': 'root', 'PASSWORD': '123456', 'HOST': '127.0.0.1', 'OPTIONS': {'init_command' : 'SET default_storage_engine=INNODB;'} } }
- 执行migrate,需要生成三个表,而不需要makemigration的原因是在安装的social_django中已经有了ini文件,可以直接进行migrate操作生成表。
在setting的AUTHENTICATION_BACKENDS中配置:
AUTHENTICATION_BACKENDS = ( 'social_core.backends.qq.QQOAuth2', 'social_core.backends.weibo.WeiboOAuth2', 'social_core.backends.weixin.WeixinOAuth2', 'django.contrib.auth.backends.ModelBackend', ... )
其中的qq、weibo和微信名称都是在'social_core.backends中有定义的。
配置TEMPLATES
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 。。。。。。 'social_django.context_processors.backends', #第三方登录 'social_django.context_processors.login_redirect', #第三方登录重定向 ], }, }, ]
在urls的urlpatterns中添加访问url,该url会封装了两个url,一个是登录至第三方平台,并且传回Authorization Code回来,第二个是用code去获取Access Token拿到用户信息,然后返回本系统,如果本系统登陆了的话就会将第三方平台的账号与已登录的账号做个绑定,如果没有登录则会用第三方返回的信息在本系统生成一个账号,并完成登录。
urlpatterns = [ 。。。。。。 #第三方登录url url('', include('social_django.urls', namespace='social')), ]
注意两点:
- 如果url中之前配置过login的url,如jwt的模式url(r'^login/$', obtain_jwt_token),一定要在login后面用$终止,不然会与第三方登录的url的login方法混淆。
- 在拿到Acces Token并拿到相关信息后重定向的页面是在开放平台设置的redict_url,建议返回首页index,地址是本 机的地址,也就是服务器的地址,不管是测试还是生产环境,不同于支付宝支付的返回,这里的是浏览器发起的重定向,并不会影响跳转。
在settings中配置第三方登录所需要的appkey和sppsecret
- SOCIAL_AUTH_你的第三方名称(在social_core的backend中有)_KEY = 'appkey'
- SOCIAL_AUTH_你的第三方名称(在social_core的backend中有)_SECRET = 'appsecret'
因为social_django是适用于django,获取信息返回后,返回的用户信息是给浏览器设置sessionid,但是drf的话,则是使用
Token登录,这里则需要重写返回的方法,再返回的时候设置用户“name”和“token”,具体修改的代码位于socia_core的
actions.py文件中的do_complete里,方法最后会将返回url,可以先将整个social_core拷贝至新建好的目录下。修改代码
如下:from rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler def do_complete(backend, login, user=None, redirect_name='next', *args, **kwargs): response = backend.strategy.redirect(url) payload = jwt_payload_handler(user) response.set_cookie("name", user.name if user.name else user.username, max_age=24*3600) response.set_cookie("token", jwt_encode_handler(payload)) return response # 特别需要注意的是cookie一定要设置过期时间,如上所示。
版权属于:Jolly
本文链接:https://totoro.site/index.php/archives/3/
关于转载:原创文章,禁止转载