1. 程式人生 > >Flask Web 開發 使用者認證_5

Flask Web 開發 使用者認證_5

使用者認證章節真夠長的,不過涉及到的內容確實多,繼續上一章節

這部分講到的是新使用者註冊以後,需要在郵箱裡麵點擊連結進行確認,這個在我們平時網站註冊新使用者的時候,經常會碰到

確認郵件中最簡單的確認連結是http://www.example.com/auth/confirm/<id> 這種形式的URL,其中id 是資料庫分配給使用者的數字id。使用者點選連結後,處理這個路由的檢視函
數就將收到的使用者id 作為引數進行確認,然後將使用者狀態更新為已確認。但這種實現方式顯然不是很安全,只要使用者能判斷確認連結的格式,就可以隨便指定URL中的數字,從而確認任意賬戶。解決方法是把URL 中的id 換成將相同資訊保安加密後得到的令牌。

(venv) $ python manage.py shell
>>> from manage import app
>>> from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

>>> s = Serializer(app.config['SECRET_KEY'], expires_in = 3600)                #expires_in表示這個祕鑰令牌的有限時間是多久,秒為單位
>>> token = s.dumps

({ 'confirm': 23 })                                                                   #dumps表示將{'confirm':23}轉化成安全令牌
>>> token
'eyJhbGciOiJIUzI1NiIsImV4cCI6MTM4MTcxODU1OCwiaWF0IjoxMzgxNzE0OTU4fQ.ey ...'
>>> data = s.loads(token)                                                                                       #loads則表示解析這個令牌,等於反向解碼

>>> data 
{u'confirm': 23}

接著,有了這個驗證的東西,我們起碼要為我們的模型新增這樣一個屬性

class User(UserMixin,db.Model):
__tablename__='users'
id=db.Column(db.Integer,primary_key=True)
email=db.Column(db.String(64),unique=True,index=True)
username=db.Column(db.String(64),unique=True,index=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
password_hash=db.Column(db.String(128))
confirmed = db.Column(db.Boolean,default=False)             #預設屬性是False,也就是未認證

def generate_confirmation_token(self,expiration=3600):
s=Serializer(current_app.config['SECRET_KEY'],expiration)    #這句的作用不是很明白,為什麼要匯入祕鑰,是不是使用這個功能必須要通過祕鑰?
return s.dumps({'confirm':self.id})

def confirm(self,token):
s=Serializer(current_app.config['SECRET_KEY'])
try:
data=s.loads(token)      #嘗試賦值給data......始終沒明白什麼情況下賦值會失敗?token沒有內容???
except:
return False
if data.get('confirm') !=self.id:  #如果資料內confirm對應的confirm值不是使用者的唯一id號,則返回False
return False
self.confirmed = True       
db.session.add(self)              
return True

由於更新過資料庫了,所以,需要新建一個指令碼,並更新資料庫

既然有了需要確認的這個新屬性,那在註冊之後,一般網站都會自動向你的郵箱發一份確認郵件,那這個功能就要新增在路由裡面了

from ..email import send_email

@auth.route('/register',methods=['GET','POST'])
def register():
form=RegistrationForm()
if form.validate_on_submit():
user=User(email=form.email.data,username=form.username.data,password=form.password.data)
db.session.add(user)           #這裡就要把user新增進資料庫了,因為只有這樣,才能有唯一的id生成
db.session.commit()            
token = user.generate_confirmation_token()
send_email(user.email,'Confirm Your Account','auth/email/confirm',user=user,token=token)
flash('A Confirmation email has been sent to you by email.')
return redirect(url_for('main.index'))
return render_template('auth/register.html',form=form)

之後,需要做的是,編輯郵件的內容,也就是你收到的郵件內容 auth/mail/confirm.html

<p>Dear {{ user.username }},</p>
<p>Welcome to <b>Flasky</b>!</p>
<p>To confirm your account please <a href="{{ url_for('auth.confirm', token=token, _external=True) }}">click here</a>.</p>  #這裡生成的是超連結按鈕
<p>Alternatively, you can paste the following link in your browser's address bar:</p>
<p>{{ url_for('auth.confirm', token=token, _external=True) }}</p>            #一般來說url_for生成的是相對路徑,有了_external=True以後,就可以生成包括http的全部路徑了
<p>Sincerely,</p>                    #然後上一行,通過<p>來將整段驗證程式碼顯示出來,和平時我們註冊網站時收到的郵件一模一樣
<p>The Flasky Team</p>
<p><small>Note: replies to this email address are not monitored.</small></p>

郵件內容也編輯好了,我們再來看一下,如果我們點選了確認連線,返回的頁面應該是什麼樣的

由於每個使用者的id不一樣,所以說,生成的token不一樣,故這裡的連線肯定是動態地址的

我們來編輯auth/views.py

@auth.route('/confirm/<token>')
@login_required                  #保護路由,要求你必須是在登陸狀態才能訪問這個頁面
def confirm(token):
if current_user.confirmed:         #如果使用者的狀態已經是confirmed的了,那直接範圍首頁了
return redirect(url_for('main.index'))
if current_user.confirm:              #如果使用者通過這個頁面的訪問,呼叫confirm函式並返回True了,那成功驗證
flash('You have confirmed your account. Thanks!')
else:                                               #其他情況下,驗證失敗,並返回主頁
flash('The confirmation link is invalid or has expired.')
return redirect(url_for('main.index'))

如我們平時訪問的一些網站一樣,當你還是個新手上路狀態的賬號時,你可能只能訪問一些特定的區域,也做不了任何事。

這裡就要用到前面章節說的鉤子了,說實話,我還不是很理解鉤子的原理,感覺需要去看上下文的原始碼,不過先這麼用起來吧。

對藍本來說,before_request 鉤子只能應用到屬於藍本的請求上。若想在藍本中使用針對程式全域性請求的鉤子,必須使用before_app_request 修飾器。

@auth.before_app_request                          #這句的意思,字面上理解是,在app的request響應之前,先如何如何............
def before_request():
if current_user.is_authenticated \         #如果使用者是認證過的
and not current_user.confirmed \         #但是confirmed屬性是False
and request.endpoint[:5] !='auth.'and request.endpoint !='static':     #而且,request的網址不是以auth.static開頭的
return redirect(url_for('auth.unconfirmed'))                                    #就返回到未確認的一個路由

@auth.route('/unconfirmed')
def unconfirmed():
if current_user.is_anonymous or current_user.confirmed:             #如果使用者是非普通使用者(is_anonymous對普通使用者返回False),或者已確認的,則返回主頁
return redirect(url_for('main.index'))
return render_template('auth/unconfirmed.html')             #不然,則進入未確認頁面

同時滿足以下3 個條件時,before_app_request 處理程式會攔截請求。
(1) 使用者已登入(current_user.is_authenticated() 必須返回True)。
(2) 使用者的賬戶還未確認。
(3) 請求的端點(使用request.endpoint 獲取)不在認證藍本中。訪問認證路由要獲取權
限,因為這些路由的作用是讓使用者確認賬戶或執行其他賬戶管理操作。

再來看一下未確認的頁面unconfirmed.html如何渲染

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky - Login{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>You have not confirmed your account yet.</h1>
</div>
<p>
Before you can access this site you need to confirm your account . Check your inbox , you should have received an email with a confirmation link.
</p>
Need another confirmation email? 
<a href = "{{url_for('auth.resend_confirmation',token=token, _external=True)}}">Click here to send again</a>    #注意這裡的寫法,很容易寫錯的
{% endblock %}

效果如圖


有時候,如果你的驗證令牌已經過期了,那我們需要重新發送一份郵件來確認,那怎麼辦呢?

再做一個路由......來重新發送郵件

@auth.route('/confirm')
@login_required
def resend_confirmation():
token = current_user.generate_confirmation_token()
send_email(current_user.email, 'Confirm Your Account','auth/email/confirm', user=current_user, token=token)
flash('A new confirmation email has been sent to you by email')
return redirect(url_for('main.index'))

收到的Email效果如下,還挺有那麼回事



確認完的郵件是這樣的,不過頁面內容還寫的是未完成確認,不過應該不是大問題,渲染檔案裡面加個if語句應該就可以,後面再改吧,先這樣。


這篇章終於快要結束了,還有最後一點管理使用者,另外篇幅講......

這認證使用者一章節內容實在是太飽滿了.....................................

相關推薦

Flask Web 開發 使用者認證_5

使用者認證章節真夠長的,不過涉及到的內容確實多,繼續上一章節 這部分講到的是新使用者註冊以後,需要在郵箱裡麵點擊連結進行確認,這個在我們平時網站註冊新使用者的時候,經常會碰到 確認郵件中最簡單的確認連結是http://www.example.com/auth/confir

Flask Web 開發 使用者認證

進入第二部分了,估計會很難,第一部分還有好多點的原理沒搞清楚,不過先做起來吧。 使用者認證其實說簡單點就是使用者名稱和密碼是否匹配的過程。下面這段書裡面的文件,應該說說的比較詳細,就直接複製了 設計Web 程式時,人們往往會高估資料庫中使用者資訊的安全性。如果攻擊者入侵伺

Flask Web 開發 使用者認證_6

握草,終於進入使用者認證的最終章節了,覺得作者不錯,到了這裡,已經開始讓你嘗試自己寫程式碼了 雖然在github上面 Miguelgrinberg 也放上了程式碼,不過還是儘量自己寫吧 首先是對於已經註冊認證的使用者,他們有時候想修改密碼,那我們肯定要為使用者專門放一個頁

Flask web開發》筆記2:模板---繼承、bootstrap

only world use 可能 clas 似的 () 目前 div 前言:今天重新梳理了一下前端方面的知識,發現學習東西還是要用,不然忘得快,廢話不多說,開始!! 一.模板繼承 1.概念: 書上說,模板繼承,類似Python上的繼承; 其實個人覺得和所有繼承

Flask Web開發——基於Python的Web應用開發實踐》一字一句上機實踐(下)

屬性 一個用戶 臨時 target 說明 實戰 分享圖片 ace 庫文件 目錄 前言 第8章 用戶認證 第9章 用戶角色 第10章 用戶資料 第11章 博客文章 第12章 關註者 第13章 用戶評論 第14章 應用編程接口 前言

Flask web開發之路二

一個 del 入口 return 計算機 span fig 服務器 pos 今天創建第一個flask項目,主app文件代碼如下: # 從flask這個框架導入Flask這個類 from flask import Flask #初始化一個Flask對象 # Flasks()

Flask web開發之路三

用戶訪問 abc gpo 得到 int bsp -a route ask 今天寫一個URL傳參、反轉URL、頁面跳轉和重定向 URL傳參 主app文件代碼: from flask import Flask app = Flask(__name__) @app.ro

Flask web開發之路四

color ase 如果 utf-8 pos char 渲染 turn pan jinjia2模板 模板渲染和參數傳遞 項目結構如下: 主app文件代碼: from flask import Flask,render_template app = Flask(__na

Flask web開發之路六

RM AR rac 默認 行修改 mysq ase style mysqldb 今天寫SQLAlchemy數據庫 首先介紹ORM的概念: ORM,Object類,Relationship:關系,Mapping:映射,也就是模型關系映射 flask-sqlalchemy是一

Flask web開發之路九

world art 更改 vertical all alc 綁定 integer scripts 首先介紹循環引用的問題: 當一個模塊需要引用另一個模塊的類,而另一個模塊又需要引用這個模塊的類時,就出現了循環引用,而沒法導入類,這時候可以切斷其中一條引用路徑,增加一個模塊

Flask web開發之路十四

format 數據模型 檢索 HA 分享 mysql ora add 數據庫初始 今天開始Flask的實戰,創建一個項目,實現包括用戶登錄、註冊、註銷、發表博客、評論以及檢索等功能 首先給出項目結構: 1.config.py文件: 存放各種配置信息 import os

Flask Web開發:基於Python的Web應用開發實戰》pdf 免費下載

需求 png 入行 14. 導入 框架 錯誤 pla 引用 《Flask Web開發:基於Python的Web應用開發實戰》pdf 免費下載鏈接: https://u253469.ctfile.com/fs/253469-292665036 第一部分 Flask

Flask Web開發:基於Python的Web應用開發實戰》pdf 完整版免費下載

項目 工廠 技術分享 各類 視圖 第2章 靜態文件 閱讀 擁有 《Flask Web開發:基於Python的Web應用開發實戰》.pdf pdf 完整版免費下載: https://u253469.ctfile.com/fs/253469-292665036 更多電子書下

Flask Web開發入門北京快樂8出售之文件上傳

url sele 模塊 con ESS isp accept NPU render 本章北京快樂8出售 dsluntan.com 我們介紹Flask Web開發中涉及的文件上傳模塊 定義後臺接收處理邏輯@app.route(‘/upload‘, methods=[‘POS

Flask web開發01:初識 Flask

flask python 端點 shell ask 項目 配置 環境 擴展 一、 搭建開發環境 二、Hello Flask! 三、啟動開發服務器 四、Python Shell 五、Flask 擴展 六、項目配置 七、URL 與端點 八、Flask 命令 九、模板與靜態文件

分享《Flask Web開發實戰:入門、進階與原理解析》PDF+源代碼

1.0 baidu rip 更多 aid size log fff web 下載:https://pan.baidu.com/s/1gbC5uhh_vjVbDk55_p7SOA 更多資料分享:http://blog.51cto.com/3215120 《Flask Web開

Flask Web開發實戰:入門、進階與原理解析》PDF+原始碼

下載:https://pan.baidu.com/s/1gbC5uhh_vjVbDk55_p7SOA 更多資料分享:http://blog.51cto.com/3215120 《Flask Web開發實戰:入門、進階與原理解析》PDF,帶目錄書籤,文字可以複製貼上;配套原始碼。 一本面向Python程式

(Flask Web開發:基於Python的Web應用開發實戰)------學習筆記(第2章)

第2章 程式的基本結構 本章將帶你瞭解 Flask 程式各部分的作用,編寫並執行第一個 Flask Web 程式。 2.1 初始化   所有 Flask 程式都必須建立一個程式例項,程式例項是 Flask 類的物件。   Web 伺服器使用一種名為 Web 伺服器閘

[分享]《Flask Web開發:基於Python的Web應用開發實戰(第2版)》中文PDF+源代碼

全面介紹 flask 技術 ESS nfs 圖片 ges web應用開發 復制粘貼 下載:Flask Web開發第二版《Flask Web開發:基於Python的Web應用開發實戰》第二版中文PDF,324頁,帶目錄和書簽,文字能夠復制粘貼;配套源代碼;經典書籍第二版,講解

Flask Web開發新手指南

Flask框架是Python開發的一個基於Werkzeug和Jinja 2的web開發微框架,它的優勢就是極其簡潔,但又非常靈活,而且容易學習和應用。因此Flask框架是Python新手快速開始web開發最好的選擇,此外,使用Flask框架的另一個好處在於你可以非常輕鬆地將基於Python的機器學習演算法或資