使用會話
使用會話對象是Flask中實現(xiàn)身份認證的一種方式。會話(session)讓服務(wù)端可以通過一種簡單的方式,在用戶瀏覽器的cookie中保存信息。保存的信息通過應(yīng)用的密鑰進行了加密簽名,如果用戶試圖修改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藍圖中檢查會話對象,里面若存在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)實現(xiàn)里簡單的用戶登錄的驗證機制。但是,還有一些功能沒有實現(xiàn),比如用戶的權(quán)限分級,登錄時沒有“記住我”的功能。要實現(xiàn)這些,我們可以使用flask-login擴展。
使用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)前的登錄用戶。這個代理對象在視圖和模板都是可以訪問的。所以我們在博客藍圖中自定義的 before_request 函數(shù)就可以刪掉了,而且對 g.current_user 的調(diào)用可以改為 current_user 。