使用會話
使用會話對象是Flask中實(shí)現(xiàn)身份認(rèn)證的一種方式刊头。會話(session)讓服務(wù)端可以通過一種簡單的方式增淹,在用戶瀏覽器的cookie中保存信息。保存的信息通過應(yīng)用的密鑰進(jìn)行了加密簽名,如果用戶試圖修改cookie的值听系,那么簽名就會失效。
往會話中添加數(shù)據(jù)很簡單虹菲,只需要
session['key'] = data
若要讀取數(shù)據(jù)靠胜,則可以
session['key']
要讓用戶處于登錄狀態(tài),則可以向會話里添加一個username屬性毕源,并且設(shè)為當(dāng)前用戶的用戶名:
@main_blueprint.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
session['username'] = form.username.data
return render_template('login.html', form=form)
若使用戶登出浪漠,則可以調(diào)用pop方法移除該屬性:
session.pop('username', None)
要判斷當(dāng)前用戶是否處于登錄狀態(tài),則可以在視圖函數(shù)中檢查會話里是否有username屬性霎褐,比如新建文章視圖:
@blog_blueprint.route('/new', methods=['GET', 'POST'])
def new_post():
if 'username' not in session:
return redirect(url_for('main.login'))
...
如果其它模板也需要知道當(dāng)前用戶的信息址愿,我們可以在開始響應(yīng)每個請求之前,在blog藍(lán)圖中檢查會話對象冻璃,里面若存在username响谓,就把該對象添加到g對象上,這樣就可以在模板中訪問了:
@blog_blueprint.before_request
def check_user():
if 'username' in session:
g.current_user = User.query.filter_by(
username=session['username']).first()
else:
g.current_user = None
這樣我們可以把前面的new_post修改一下:
def new_post():
if not g.current_user:
...
現(xiàn)在省艳,我們已經(jīng)實(shí)現(xiàn)里簡單的用戶登錄的驗(yàn)證機(jī)制歌粥。但是,還有一些功能沒有實(shí)現(xiàn)拍埠,比如用戶的權(quán)限分級失驶,登錄時沒有“記住我”的功能。要實(shí)現(xiàn)這些枣购,我們可以使用flask-login擴(kuò)展嬉探。
使用Flask Login
Flask-Login用來管理已登錄用戶的用戶會話擦耀,主要有以下幾個方法:
- load_user() 本函數(shù)的參數(shù)是要登錄的用戶,以及可選的“記住我”布爾值涩堤。(如果值為False眷蜓,那么關(guān)閉瀏覽器后用戶會話就會過期。如果值為True胎围,那么會在瀏覽器中寫入一個長期有效的cookie吁系,使用這個cookie可以復(fù)現(xiàn)用戶會話。)
- logout_user() 刪除并重設(shè)用戶會話白魂。
- is_active() 如果允許用戶登錄汽纤,必須返回True,否則返回False福荸。
- is_authenticated() 如果用戶已經(jīng)登錄蕴坪,必須返回True,否則返回False敬锐。
- is_anonymous() 對普通用戶返回False背传。
Flask Login還提供了一個 current_user 代理對象來訪問當(dāng)前的登錄用戶。這個代理對象在視圖和模板都是可以訪問的台夺。所以我們在博客藍(lán)圖中自定義的 before_request 函數(shù)就可以刪掉了径玖,而且對 g.current_user 的調(diào)用可以改為 current_user 。