天天看點

用flask開發個人部落格(33)—— 使用itsdangerous進行賬戶的确認一、定義郵件發送的方法send_email二、在User模型中定義生成令牌和驗證令牌的方法三、定義發送郵件的視圖函數四、定義确認路由

        我們在某個網站進行開戶時,往往會收到網站發過來的确認郵件,隻有點選确認郵件裡面的連結後,我們所開的賬戶才能生效。本文主要介紹在flask中進行這種确認機制的方法。

一、定義郵件發送的方法send_email

        首先,我們在email.py中定義一個發送郵件的方法send_email:

from flask_mail import Message
from app import mail
from flask import render_template

def send_email(to,subject,template,**kwargs):
    msg=Message("[TecnologyDreamer]"+subject,sender='[email protected]',recipients=[to])
    msg.body=render_template(template+'.txt',**kwargs)
    msg.html=render_template(template+'.html',**kwargs)
    mail.send(msg)
           

        send_email接收4個參數,第1個參數是發送郵件的目标位址,第2個參數是郵件主題,第3個參數是模闆的名稱,第4個參數是一個字典,用來渲染模闆。我們在tempates目錄下建立mail目錄,在mail下建立new_user.html和new_user.txt分别作為郵件的文本和html模闆。new_user.htm和new_user.txt模闆的内容如下:

Welcome {{ user.username }}!
Click {{ url_for('main.confirm',token=token,_external=True)}} to confirm.
           

二、在User模型中定義生成令牌和驗證令牌的方法

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 
class User(db.Model,UserMixin):
    __tablename__='users'
    ......
confirmed=db.Column(db.Boolean,default=False) 
def generate_token(self,expiration=3600): 
    s=Serializer('secret key',expiration) 
    return s.dumps({'confirm':self.id}) 
def confirm(self,token): 
    s=Serializer('secret key') 
    data=s.loads(token) 
    if data.get('confirm')!=self.id: 
        return False 
    self.confirm = True 
    db.session.add(self) 
    return True
           

        我們在User模型中增加了一個confirmed字段,用來表示使用者是否得到了确認。generate_token方法用來産生令牌,Serializer是我們從itsdangerours引入的序列化的對象,它的第一個參數是加密的秘鑰,我們這裡設定成了字元串'secret key',第二個參數是要加密的字段。它傳回序列化對象的一個方法dumps的執行結果,将由confirm和id組成的字典序列化成一個令牌。confirm方法用來驗證令牌的有效性,它調用序列化對象的loads方法,将令牌還原成加密之前的字典對象,最後得到裡面的id值和user的id進行比較。

三、定義發送郵件的視圖函數

        我們在上一文的注冊視圖函數register基礎之上進行修改:

@main.route('/register',methods=['GET','POST'])
def register():
    form=RegisterForm()
    if form.validate_on_submit():
        user=User(username=form.name.data,password=form.password1.data)
        db.session.add(user)
        db.session.commit()
        token=user.generate_token()
        send_email(form.email.data,'Confirm Account','mail/new_user',user=user,token=token)
    return render_template('register.html',form=form)
           

        這裡面我們在建立一個user之後,要手動調用db.session.commit進行送出,因為後面我們需要調用方法user.generate_token(),這個方法需要用到user的id字段,而id隻有我們将user存入資料庫後才會生成。

四、定義确認路由

        最後一步是定義确認路由,即使用者在其郵件中點選的url,這個url含有令牌,而對應的路由中這個令牌被做成了變量,被傳給視圖函數。我們在該視圖函數中調用user的confirm方法進行确認,是否和current_user的id一緻。

@main.route('/confirm/<token>')
@login_required
def confirm(token):
    if not current_user.confirmed:
        if current_user.confirm(token):
            flash('Confirm succeed')
        else: 
            flash('Confirm fail')
    return redirect(url_for('main.register'))
           

        現在,輸入http://localhost:5000/register,并點選注冊按鈕之後,就會給注冊的郵箱發一封确認郵件,如下所示:

用flask開發個人部落格(33)—— 使用itsdangerous進行賬戶的确認一、定義郵件發送的方法send_email二、在User模型中定義生成令牌和驗證令牌的方法三、定義發送郵件的視圖函數四、定義确認路由

        點解連接配接就完成了注冊。

Github位置:

https://github.com/HymanLiuTS/flaskTs

克隆本項目:

Git  clone  Git @github.com:HymanLiuTS/flaskTs.Git

擷取本文源代碼:

git checkout FL33

繼續閱讀