在Django中進行註冊用戶的郵件確認

以前利用Flask寫博客時(http://hbnnlove.sinaapp.com),我對註冊模塊的邏輯設計很簡單,就是用戶填寫註冊表單,而後提交,數據庫會更新User表中的數據,字段主要有用戶名,哈希後的密碼,郵件。html

但感受這樣設計有些簡單,用戶註冊時有必要驗證一下用戶的註冊郵件,看是不是他本身的郵箱。
本文主要介紹我在利用Django寫博客時,採用的註冊方法。首先說一下總體邏輯思路:
 
  • 處理用戶註冊數據,
  • 產生token,生成驗證URL,
  • 發送驗證郵件,
  • 用戶登陸網址,進行驗證,
  • 驗證處理。
 
具體步驟:
 
一、添加用戶
        在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,此時還不是有效用戶。
 
二、郵件驗證
 郵件驗證主要有兩步,一是產證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})
相關文章
相關標籤/搜索