django 注册、登录及第三方接口程序(4):扩展邮箱注册,登录,微博登录
2015-01-17 16:01
661 查看
文章来源:http://www.cnblogs.com/BeginMan/p/3801723.html
1.setting配置
2.model
这里包含了扩展的方法和字段,贴代码如下,不明白可以看官网详解。
这样就可以使用扩展字段了。
首先配置的东西如key等,建议放在settings中,如下:
url路由就自己写吧,这里给出视图方法,
这里自己写了个微博类,用于处理微博登录的基础数据,感兴趣的也可以看看,
1.邮箱注册
这里需要扩展User,两种解决办法,1,注册时将email字段内容赋给username,这种瞒天过海型的,另一种就是扩展user,这里介绍django1.5的扩展方法。1.setting配置
AUTH_USER_MODEL = 'manager.MyUser' # 扩展表的位置,appname.Model, MyUser是manager app下models中的用户类 AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend', 'manager.models.CustomAuth') # 后端认证
2.model
这里包含了扩展的方法和字段,贴代码如下,不明白可以看官网详解。
#coding=utf-8 from django.conf import settings from django.db import models from django.contrib.auth.models import BaseUserManager, AbstractBaseUser class UserManager(BaseUserManager): """通过邮箱,密码创建用户""" def create_user(self, email,username, password=None,type=None,**kwargs): if not email: raise ValueError(u'用户必须要有邮箱') user = self.model( email=UserManager.normalize_email(email), username=username, type=type if type else 0 ) user.set_password(password) if kwargs: if kwargs.get('sex', None): user.sex = kwargs['sex'] if kwargs.get('is_active', None): user.is_active=kwargs['is_active'] if kwargs.get('uid', None): user.uid=kwargs['uid'] if kwargs.get('access_token', None): user.access_token=kwargs['access_token'] if kwargs.get('url', None): user.url=kwargs['url'] if kwargs.get('desc', None): user.desc=kwargs['desc'] if kwargs.get('avatar', None): user.avatar=kwargs['avatar'] user.save(using=self._db) return user def create_superuser(self, email, username, password): user = self.create_user(email, password=password, username=username, ) user.is_admin = True user.save(using=self._db) return user class MyUser(AbstractBaseUser): """扩展User""" email = models.EmailField(verbose_name='Email', max_length=255, unique=True,db_index=True) username = models.CharField(max_length=50, unique=True, db_index=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) type = models.IntegerField(default=0) # 类型,0本站,1微博登录 sex = models.IntegerField(default=1) # sex uid = models.CharField(max_length=50, null=True) # weibo uid access_token = models.CharField(max_length=100, null=True) # weibo access_token url = models.URLField(null=True) # 个人站点 desc = models.CharField(max_length=2000, null=True) # 个人信息简介 avatar = models.CharField(max_length=500, null=True) # 头像 objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['username'] def get_full_name(self): # The user is identified by their email address return self.email def get_short_name(self): # The user is identified by their email address return self.email def __unicode__(self): return self.email def has_perm(self, perm, obj=None): "Does the user have a specific permission?" # Simplest possible answer: Yes, always return True def has_module_perms(self, app_label): "Does the user have permissions to view the app `app_label`?" # Simplest possible answer: Yes, always return True @property def is_staff(self): "Is the user a member of staff?" # Simplest possible answer: All admins are staff return self.is_admin class Meta: db_table = 'user' class CustomAuth(object): """自定义用户验证""" def authenticate(self, email=None, password=None): try: user = MyUser.objects.get(email=email) if user.check_password(password): return user except MyUser.DoesNotExist: return None def get_user(self, user_id): try: user = MyUser.objects.get(pk=user_id) if user.is_active: return user return None except MyUser.DoesNotExist: return None
这样就可以使用扩展字段了。
2.注册/登录/更改密码表单
这里不罗嗦了,看代码就行了,总贴代码唯恐管理员移除了我的博客,吐槽下,博客园后台管理编辑文章markdown方式的超级烂。class LoginForm(forms.Form): """ =============================================================================== function: 表单登录类 developer: BeginMan add-time 2014/6/3 =============================================================================== """ email = forms.EmailField(label=u'邮箱',max_length=100,widget=forms.TextInput( attrs={'class': 'form-control', 'placeholder': u'邮箱', 'required': '', 'autofocus': ''} ), ) pwd = forms.CharField(label=u'密码',widget=forms.PasswordInput( attrs={'class': 'form-control', 'placeholder': u'密码', 'required': ''} ) ) auto_login = forms.BooleanField(label=u'记住密码',required=False, widget=forms.CheckboxInput(attrs={'value': 1}), ) def __init__(self, request=None, *args, **kwargs): self.request = request self.user_cache = None self.auth_login = None super(LoginForm, self).__init__(*args, **kwargs) def clean(self): email = self.cleaned_data.get('email') password = self.cleaned_data.get('pwd') auth_login = self.cleaned_data.get('auth_login', None) if email and password: if not MyUser.objects.filter(email=email).exists(): raise forms.ValidationError(u'该账号不存在') self.user_cache = authenticate(email=email, password=password) if self.user_cache is None: raise forms.ValidationError(u'邮箱或密码错误!') elif not self.user_cache.is_active: raise forms.ValidationError(u'该帐号已被禁用!') if auth_login: # 如果用户勾选了自动登录 self.auth_login = True return self.cleaned_data def get_user_id(self): """获取用户id""" if self.user_cache: return self.user_cache.id return None def get_user(self): """获取用户实例""" return self.user_cache def get_auto_login(self): """是否勾选了自动登录""" return self.auth_login def get_user_is_first(self): """获取用户是否是第一次登录""" is_first = False if self.user_cache and self.user_cache.type == -1: is_first = True self.user_cache.type == 0 self.user_cache.save() return is_first class RegisterForm(forms.Form): """ =============================================================================== function: 表单注册类 developer: BeginMan add-time 2014/6/3 =============================================================================== """ email = forms.EmailField(label=u'Email', max_length=100, widget=forms.TextInput( attrs={'class': 'form-control', 'placeholder': u'Email', 'required': '', 'autofocus': ''} ), ) pwd = forms.CharField(label=u'密码',widget=forms.PasswordInput( attrs={'class': 'form-control', 'placeholder': u'密码', 'required': ''} ) ) pwd2 = forms.CharField(label=u'密码(重复)',widget=forms.PasswordInput( attrs={'class': 'form-control', 'placeholder': u'重复密码', 'required': ''} ) ) def __init__(self, request=None, *args, **kwargs): self.request = request self.user = None super(RegisterForm, self).__init__(*args, **kwargs) def clean(self): data = self.cleaned_data email = data.get('email') pwd = data.get('pwd') pwd2 = data.get('pwd2') if MyUser.objects.filter(email=email).exists(): raise forms.ValidationError(u'该邮箱已被注册') if pwd != pwd2: raise forms.ValidationError(u'两次输入密码不一致') if pwd2 == pwd and len(pwd) < 6: raise forms.ValidationError(u'密码不能小于6位') # 用户注册 # type = -1表示首次 avatar = random.choice(range(35)) avatar = '/site_media/avatar/%s.jpg' % avatar # 生成用户并验证 username = email.split('@') if len(username) !=2 : raise forms.ValidationError(u'邮箱格式不对') else: username = ValidUs(username[0]) self.user = MyUser.objects.create_user(email=email, username=username, password=pwd, type=-1, avatar=avatar).id return data def get_user(self): """获取用户实例""" return self.user class PasswordForm(forms.Form): """ =============================================================================== function: 用户修改密码 developer: BeginMan add-time 2014/6/3 =============================================================================== """ oldpwd = forms.CharField(label=u'原始密码', widget=forms.PasswordInput( attrs={'class': 'form-control', 'placeholder': u'原始密码', 'required': ''}) ) password1 = forms.CharField(label=u'新密码', widget=forms.PasswordInput( attrs={'class': 'form-control', 'placeholder': u'密码长度在5-12位', 'required': ''}) ) password2 = forms.CharField(label=u'在输入一次', widget=forms.PasswordInput( attrs={'class': 'form-control', 'placeholder': u'在输入一次', 'required': ''}) ) def __init__(self, user=None, *args, **kwargs): self.user = user self.newpwd = None super(PasswordForm, self).__init__(*args, **kwargs) def clean(self): cleaned_data = super(PasswordForm, self).clean() oldpwd = cleaned_data.get("oldpwd") password1 = cleaned_data.get("password1") password2 = cleaned_data.get("password2") if not self.user.check_password(oldpwd): msg = u"原密码错误。" self._errors["oldpwd"] = self.error_class([msg]) # raise forms.ValidationError(u'原密码错误') if password1 and password2: if password1 != password2: msg = u"两个密码字段不一致。" self._errors["password2"] = self.error_class([msg]) if not 4 < len(password1) < 13: msg = u"密码要在5-12位之间。" self._errors["password1"] = self.error_class([msg]) return cleaned_data class AvatarForm(forms.Form): """ =============================================================================== function: 用户修改头像 developer: BeginMan add-time 2014/6/3 =============================================================================== """ avatar = forms.ImageField(label=u'图片上传', widget=forms.FileInput( attrs={'class': 'form-control', 'placeholder': u'图片上传', 'required': ''}) ) def clean(self): cleaned_data = super(AvatarForm, self).clean() image = cleaned_data.get("avatar", None) if image: if image.content_type not in ['image/jpeg', 'image/png']: raise forms.ValidationError(u'你上传的是图片吗?') else: img = Image.open(image) w, h = img.size max_width = max_height = 1000 if w >= max_width or h >= max_height: raise forms.ValidationError(u'上传的图片要尺寸要小于或等于%s宽,%s高' % (max_width, max_height)) if img.format.lower() not in ['jpeg', 'pjpeg', 'png', 'jpg']: raise forms.ValidationError(u'暂时只接纳JPEG or PNG.') #validate file size if len(image) > (1 * 1024 * 1024): raise forms.ValidationError('Image file too large ( maximum 1mb )') else: raise forms.ValidationError(u'额,图片呢?') return cleaned_data
3.微博登录
如果你的网站想接入微博登录,那么先看看新浪开发者平台上的python SDK,API等,这里提供自己的处理方式,还是贴代码。。首先配置的东西如key等,建议放在settings中,如下:
# 微博登陆 URL = 'http://codetheme.sinaapp.com' APP_KEY = '你的' APP_SERCET = '你的' CALLBACK_URL = URL+'/login/weibo_check/' # 回调地址
url路由就自己写吧,这里给出视图方法,
def weiboLogin(request): """微博登录""" client = APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SERCET, redirect_uri=settings.CALLBACK_URL) url = client.get_authorize_url() return HttpResponseRedirect(url) def weibo_check(request): code = request.GET.get('code', None) now = datetime.datetime.now() if code: client = APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SERCET, redirect_uri=settings.CALLBACK_URL) r = client.request_access_token(code) access_token = r.access_token # 返回的token,类似abc123xyz456 expires_in = r.expires_in # token过期的UNIX时间:http://zh.wikipedia.org/wiki/UNIX%E6%97%B6%E9%97%B4 uid = r.uid # 在此可保存access token client.set_access_token(access_token, expires_in) request.session['access_token'] = access_token request.session['expires_in'] = expires_in request.session['uid'] = uid user = SupserWeibo(access_token=access_token, uid=uid, request=request) # 实例化超级微博类 # 更新数据库 if MyUser.objects.filter(uid=uid).exists(): MyUser.objects.filter(uid=uid).update(last_login=now) user.Login() # 登陆 return HttpResponseRedirect('/') else: # 创建用户并登陆 u_id = user.createUser() if u_id: return HttpResponseRedirect('/manage/user/%s/' %u_id) return HttpResponse('/404/')
这里自己写了个微博类,用于处理微博登录的基础数据,感兴趣的也可以看看,
#coding=utf-8 """ ================================== function: 基于新浪微博API,对微博登陆进行扩展 addDate: 2014-06-04 author: BeginMan ================================== """ from django.conf import settings import urllib import urllib2 import simplejson as json from manager.models import MyUser from django.contrib.auth import authenticate, login, logout from django.http import HttpResponseRedirect import datetime # 默认图片 DEFAULT_PIC = 'http://images.cnitblog.com/news/66372/201405/271116202595556.jpg' # 用户信息 USER_INFO_URL = 'https://api.weibo.com/2/users/show.json' # 发送微博 SEND_WEIBO_URL = 'https://api.weibo.com/2/statuses/upload_url_text.json' user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:28.0) Gecko/20100101 Firefox/28.0' headers = {'User-Agent': user_agent} class SupserWeibo(object): def __init__(self, access_token, uid, request=None, **kwargs): self.access_token = access_token self.uid = uid self.request = request self.user_cache = None self.kwargs = kwargs def createUser(self): """创建用户""" userInfo = self.getUserInfo() username=userInfo.get('screen_name') if MyUser.objects.filter(username=username).exists(): username = username+'[weibo]' u_id = 0 try: new_user = MyUser.objects.create_user( email=str(self.uid) + '@weibo.com', username=username, password=self.uid, type=1, sex=int(userInfo.get('sex', 1)), uid=self.uid, access_token=self.access_token, url=userInfo.get('url', ''), desc =userInfo.get('description', ''), avatar=userInfo.get('avatar_large') ) u_id = new_user.id except: pass self.Login() # 登陆 return u_id def getUserInfo(self): """获取微博用户信息""" data = {'access_token': self.access_token, 'uid': self.uid} params = urllib.urlencode(data) values = urllib2.Request(USER_INFO_URL+'?%s' %params, headers=headers) response = urllib2.urlopen(values) result = json.loads(response.read()) if result.get('error_code', None): # 写入日志 print '获取用户信息失败' return False return result def SendWeibo(self): """用户发送微博""" status = self.kwargs.get('status', None) # 微博内容 visible = self.kwargs.get('visible', 0) # 微博的可见性,0:所有人能看,1:仅自己可见,2:密友可见,3:指定分组可见,默认为0。 url = self.kwargs.get('url', DEFAULT_PIC) # 配图 result = {} if status: data = {'access_token': self.access_token, 'status': status, 'visible':visible, 'url':url} params = urllib.urlencode(data) values = urllib2.Request(USER_INFO_URL+'?%s' %params, headers=headers) response = urllib2.urlopen(values) result = json.loads(response.read()) if result.get('error_code', None): # 写入日志 print '发送微博失败' return False return True return result def Login(self): """登陆""" user_ = MyUser.objects.filter(uid=self.uid)[0] user = authenticate(email=user_.email, password=self.uid) login(self.request, user)
相关文章推荐
- django 注册、登录及第三方接口程序(4):扩展邮箱注册,登录,微博登录
- django 注册、登录及第三方接口程序(2):扩展User表
- django 注册、登录及第三方接口程序(3):验证之正则表达式
- django 注册、登录及第三方接口程序(1):基础知识
- django 注册、登录及第三方接口程序(1):基础知识
- APP带第三方微博、微信、QQ等登录注册的登录注册流程分解
- django用户注册、登录、注销和用户扩展
- 转载django用户注册、登录、注销和用户扩展
- django用户注册、登录、注销和用户扩展的示例
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
- 微博第三方登录接口
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
- 一个用POP3扩展协议实现的收发SSL验证类邮箱的小程序
- 第三方程序调用django的models
- go语言实现一个简单的登录注册web小程序
- android 注册、登录实现程序
- python django 用户注册验证登录。。。
- 新浪微博客户端源代码-新浪微博OAuth2.0接口--回调地址未填而出现第三方调用错误解决方法
- c# 编写winform登录注册程序(二,注册部分)
- 如何在 Chrome 浏览器安装 Web Store 外的第三方扩展程序