关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
前面写了3篇有个OAuth第三方登录的博文:QQ第三方登录、新浪微博第三方登录和Github第三方登录。
由于一开始没有整体的构架,导致写了这几个第三方账号登录之后,代码有很多重复且冗余。
所以对这部分功能进行整理并优化。
有一点需要说明,本篇博文不涉及具体OAuth实现的代码,着重讲功能整合和结构性的东西。
具体实现OAuth代码和这3个第三方账号的OAuth申请可以参考上面3篇博文。
源码我也放在Github上:https://github.com/HaddyYang/django-oauth
至于都OAuth还不太理解的小伙伴们,看下图:
实际上,OAuth相当于第三方账号网站提供的接口,需要先认证,拿到通行令牌access_token,才能继续调用接口获取数据。有不少人卡在这个地方。看上图再理解一下,准备进入正题。
通过之前3篇博文说是3个第三方网站OAuth开发之后,发现设置的内容基本一致。若把设置的数据放在settings.py文件会导致不方便维护,所以我考虑把这些设置放在数据库中。则需要创建模型,打开OAuth的models.py文件:
#coding:utf-8 from django.db import models #若不是使用系统的用户认证,可以换成你自己的用户系统 from django.contrib.auth.models import User class OAuth_type(models.Model): """OAuth类型""" type_name = models.CharField(max_length = 12) title = models.CharField(max_length = 12) #图片上传的路径可以修改成自己的 img = models.FileField(upload_to='static/img/connect') #oauth基本设置 client_id = models.CharField(max_length = 24, default='') client_secret = models.CharField(max_length = 48, default='') redirect_uri = models.URLField(default='') scope = models.CharField(max_length = 24, default='') #oauth请求链接 url_authorize = models.URLField(default='', blank=True) url_access_token = models.URLField(default='', blank=True) url_open_id = models.URLField(default='', blank=True) url_user_info = models.URLField(default='', blank=True) url_email = models.URLField(default='', blank=True) def __unicode__(self): return self.type_name class OAuth_ex(models.Model): """User用户绑定""" user = models.ForeignKey(User) #和User关联的外键 openid = models.CharField(max_length = 64) oauth_type = models.ForeignKey(OAuth_type, default=1) #关联账号的类型 def __unicode__(self): return u'<%s>' % (self.user)
OAuth_type模型是保存OAuth相关设置,分为3部分:第1部分填写该类型相关的信息;第2部分填写基本的设置(例如密匙、回调地址等);第3部分填写相关数据请求链接。
OAuth_ex模型是保存第三方账号和自己网站用户关联信息。
由于OAuth要设置的内容比较多,在django后台管理中可以对其分组显示。打开OAuth的admin.py文件:
#coding:utf-8 from django.contrib import admin from .models import OAuth_type, OAuth_ex # Register your models here. class OAuthTypeAdmin(admin.ModelAdmin): list_display=('id','type_name', 'title', 'img') #分组表单 fieldsets = ( (u'OAuth类型信息', { "fields":('type_name', 'title', 'img') }), (u'OAuth基本设置', { "fields":('client_id','client_secret','redirect_uri','scope') }), (u'OAuth请求链接', { "fields":('url_authorize','url_access_token','url_open_id','url_user_info','url_email') }) ) class OAuthAdmin(admin.ModelAdmin): list_display=('id', 'user', 'openid','oauth_type') admin.site.register(OAuth_ex, OAuthAdmin) admin.site.register(OAuth_type, OAuthTypeAdmin)
效果如下图:
把OAuth设置信息放到模型中之后,发送认证信息到第三方网站的请求方法就可以统一写成1个方法(oauth的views.py文件):
#coding:utf-8 from django.http import Http404 from django.forms.models import model_to_dict #模型对象转字典 from .models import OAuth_ex, OAuth_type from .oauth_client import OAuth_Base def _get_oauth(type_name, state): """获取对应的OAuth对象""" try: oauth_type = OAuth_type.objects.get(type_name = type_name) except: raise Http404 kw = model_to_dict(oauth_type) kw['state'] = state return OAuth_Base.Get_OAth(**kw)
此处,把模型转成dict字典,再调用oauth_client.py文件中的OAuth_Base基类静态方法获取对应的第三方账号登录处理对象。
至于oauth_client.py文件中的4个类:OAuth_Base是基类;OAuth_QQ、OAuth_Sina、OAuth_Github是继承了OAuth_Base类,实现具体的OAuth方法。若你要新增其他的第三方账号登录,可以参考这3个类。
总体流程如下图:
通过路由设置传递OAuth第三方账号类型,读取配置,选择对应的类。获取到已经写好的类之后,再利用得到的用户信息进一步处理。
到这里OAuth框架性的东西和整理的部分已经讲解完毕。(很多东西前面的博文已经讲解了)
但对于整个用户认证系统来说,只是完成一半的功能而已。还有一半的功能是绑定用户。这部分的代码根据自己的网站具体情况实现。每个网站的用户认证系统不太可能一样。
我的网站用户认证是采用Django自带的,并使用邮箱地址作为用户名。
所以在我分享的源码中可以找到form.py文件,此文件是绑定用户的表单。另外templates中的模版文件也是我网站使用到的。
form.html是通用表单;message.html是信息提示页面。
对应的代码我也封装了,具体可以参考我的源码:https://github.com/HaddyYang/django-oauth
wongjyusing
博主,我现在使用的是python3, urllib2用不了,我试过用urllib.request() 这有什么方法解决呢?
2018-07-13 21:30 回复
wongjyusing
我试过用urllib.request() ,仍然不行,这有什么方法解决呢?
2018-07-13 21:45 回复