在Django中进行用户注册和邮箱验证的方法


Posted in Python onMay 09, 2016

本文主要介绍我在利用Django写文章时,采用的注册方法。首先说一下整体逻辑思路:

•处理用户注册数据,

•产生token,生成验证URL,

•发送验证邮件,

•用户登录网址,进行验证,

•验证处理。

具体步骤:

1、添加用户

在Django中自带的User表中,有一个is_active字段,默认值是True,即用户填完表单提交之后,就可以进行登录。我们这里首先将is_acitve字段设为False,也就是说,必须经过后续的邮箱验证,才能够正常登录。

部分代码:

if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
#new_user = form.save()
username,password,email = cd['username'],cd['password1'],cd['email']
user = User.objects.create(username=username, password=password, email=email, is_active=False)
user.set_password(password)
user.save()

提交后,数据库中会增加一条记录,但is_acitve字段为False,此时还不是有效用户。

2、邮件验证

邮件验证主要有两步,一是产证token,即加密,二是处理验证链接。

1)产生token

之前我采用的是简单的base64加解密方法, 但终究是太简单了,后来看到关于Flask的验证用户的文章(http://python.jobbole.com/81410/),就采用了itsdangerous序列化方法,其实Flask的session就用了itsdangerous序列化。我使用它的重要原因是它自带有一个时间戳,而且序列化方法要比单纯的使用base64给力得多。

代码:

from itsdangerous import URLSafeTimedSerializer as utsr
import base64
import re

class Token():

def __init__(self,security_key):
self.security_key = security_key
self.salt = base64.encodestring(security_key)
def generate_validate_token(self,username):
serializer = utsr(self.security_key)
return serializer.dumps(username,self.salt)
def confirm_validate_token(self,token,expiration=3600):
serializer = utsr(self.security_key)
return serializer.loads(token,
salt=self.salt,
max_age=expiration)

security_key就是settings.py中设置的SECRET_KEY,salt是经过base64加密的SECRET_KEY, generate_validate_token函数通过URLSafeTimedSerializer在用户注册时生成一个令牌。用户名在令牌中被编了码。生成令牌之后,会将带有token的验证链接发送到注册邮箱。在confirm_validate_token函数中,只要令牌没过期,那它就会返回一个用户名,过期时间为3600秒。

发送邮件函数代码:

token = token_confirm.generate_validate_token(username)
#active_key = base64.encodestring(username)
#send email to the register email
message = "\n".join([
u'{0},欢迎加入我的博客'.format(username),
u'请访问该链接,完成用户验证:',
'/'.join([DOMAIN,'account/activate',token])
])
send_mail(u'注册用户验证信息',message, None,[email])

2)处理邮件验证

就是对应验证链接的视图函数,该函数的主要目的是将User表中用户的is_active字段更新为True。

def active_user(request,token):
username = token_confirm.confirm_validate_token(token)
user = User.objects.get(username=username)
user.is_active = True
user.save()

这里要说一下url的设置。经过itsdangerous产生的token是随机且规律的,说它规律是因为它是由三部分组成,并由点号隔开。类似这样:Imhibm4i.Cg-UAQ.n7ZI2N9kUZ1eOcfBtxlMOdOYYE0。说它随机是因为每一部分的内容可能不仅仅含有字母数字,可能还含有连接符-,_。因此url应该是:url(r'^account/activate/(?P<token>\w+.[-_\w]*\w+.[-_\w]*\w+)/$','blog.views.active_user',name='active_user')

经过上述操作后,用户就可以利用刚注册的用户名进行登录了。

贴出完整代码:

from utils.token import Token
from django.core.mail import send_mail
from .forms import UserLoginForm,CustomUserCreationForm
token_confirm = Token(SECRET_KEY)

def Register(request):

if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
#new_user = form.save()
username,password,email = cd['username'],cd['password1'],cd['email']
user = User.objects.create(username=username, password=password, email=email, is_active=False)
user.set_password(password)
user.save()
token = token_confirm.generate_validate_token(username)
#active_key = base64.encodestring(username)
#send email to the register email
message = "\n".join([
u'{0},欢迎加入我的博客'.format(username),
u'请访问该链接,完成用户验证:',
'/'.join([DOMAIN,'account/activate',token])
])
send_mail(u'注册用户验证信息',message, None,[cd['email']])
#user = auth.authenticate(username=username,password=password)
#auth.login(request,user)
return HttpResponse(u"请登录到注册邮箱中验证用户,有效期为1个小时。")
else:
form = CustomUserCreationForm()
return render(request,'register.html',{'form':form})
def active_user(request,token):
"""
the view function is used to accomplish the user register confirm,only after input the link
that sent to the register email,user can login the site normally.
:param request:
:param activate_key:the paragram is gotten by encrypting username when user register
:return:
"""
try:
username = token_confirm.confirm_validate_token(token)
except:
return HttpResponse(u'对不起,验证链接已经过期')
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
return HttpResponse(u'对不起,您所验证的用户不存在,请重新注册')
user.is_active = True
user.save()
confirm = u'验证成功,请进行登录操作。'
return HttpResponseRedirect('/account/login',{'confirm':confirm})

以上所述是小编给大家介绍的在Django中进行用户注册和邮箱验证的方法,希望对大家有所帮助!

Python 相关文章推荐
python赋值操作方法分享
Mar 23 Python
pygame学习笔记(5):游戏精灵
Apr 15 Python
python之Socket网络编程详解
Sep 29 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
Mar 05 Python
详解tensorflow载入数据的三种方式
Apr 24 Python
django静态文件加载的方法
May 20 Python
不知道这5种下划线的含义,你就不算真的会Python!
Oct 09 Python
详谈Python 窗体(tkinter)表格数据(Treeview)
Oct 11 Python
python flask框架实现传数据到js的方法分析
Jun 11 Python
为什么从Python 3.6开始字典有序并效率更高
Jul 15 Python
详解如何在cmd命令窗口中搭建简单的python开发环境
Aug 29 Python
Python numpy大矩阵运算内存不足如何解决
Nov 19 Python
Python数据类型详解(三)元祖:tuple
May 08 #Python
Python数据类型详解(二)列表
May 08 #Python
Python数据类型详解(一)字符串
May 08 #Python
Python常用知识点汇总
May 08 #Python
Python对list列表结构中的值进行去重的方法总结
May 07 #Python
Python环境下安装使用异步任务队列包Celery的基础教程
May 07 #Python
Python编写电话薄实现增删改查功能
May 07 #Python
You might like
php实现SAE上使用storage上传与下载文件的方法
2015/06/29 PHP
Yii 访问 Gii(脚手架)时出现 403 错误
2018/06/06 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
Prototype Number对象 学习
2009/07/19 Javascript
js 点击页面其他地方关闭弹出层(示例代码)
2013/12/24 Javascript
用jQuery实现的智能隐藏、滑动效果的返回顶部代码
2014/03/18 Javascript
浅析jQuery中调用ajax方法时在不同浏览器中遇到的问题
2014/06/11 Javascript
window.location的重写及判断location是否被重写
2014/09/04 Javascript
使用JQuery库提供的扩展功能实现自定义方法
2014/09/09 Javascript
js以分隔符分隔数组中的元素并转换为字符串的方法
2016/11/16 Javascript
AngularJS表格样式简单设置方法示例
2017/03/03 Javascript
javascript将url解析为json格式的两种方法
2017/08/18 Javascript
Bootstrap Table快速完美搭建后台管理系统
2017/09/20 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
2018/01/25 Javascript
Vue Cli3 创建项目的方法步骤
2018/10/15 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
2019/01/23 Javascript
vue项目中使用多选框的实例代码
2020/07/22 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
[33:33]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第二场 11.27
2020/11/30 DOTA
Django集成百度富文本编辑器uEditor攻略
2014/07/04 Python
基于进程内通讯的python聊天室实现方法
2015/06/28 Python
python轻松查到删除自己的微信好友
2016/01/10 Python
Python实现的调用C语言函数功能简单实例
2019/03/13 Python
Python通用函数实现数组计算的方法
2019/06/13 Python
Flask框架单例模式实现方法详解
2019/07/31 Python
HTML 5 input placeholder 属性如何完美兼任ie
2014/05/12 HTML / CSS
GUESS德国官网:美国牛仔服装品牌
2017/02/14 全球购物
泰国网上购物:Shopee泰国
2018/09/14 全球购物
精致的手工皮鞋:Shoe Embassy
2019/11/08 全球购物
澳大利亚最便宜的网上药房:Chemist Warehouse
2020/01/30 全球购物
网络通讯中,端口有什么含义,端口的取值范围
2012/11/23 面试题
体育老师的教学自我评价分享
2013/11/19 职场文书
一名老师的自我评价
2014/02/07 职场文书
上班迟到检讨书
2015/05/06 职场文书
亮剑观后感600字
2015/06/05 职场文书
观后感开头
2015/06/19 职场文书