最近需要使用Python開發web系統,主要用到的框架就是Flask,前端使用Jinja2模板引擎和Bootstrap,web容器使用Cherrypy,其中關於Login管理的使用了Flask-Login插件。
基本上也是從零學起,前前后后花了有好幾個月的時間,還是在借鑒了已有的一些項目基礎上。在開發的過程中有很多的想法和體會,記錄下來,有不對的地方歡迎大家指正。
在處理登錄管理的部分,在 Flask-Login 中,如果你不特殊處理的話,session 是在你關閉瀏覽器之后失效的,而如果不關閉瀏覽器的話,失效的時間據說是1年,還是1個月,這個地方沒看到官方說法,總之是很長,在某些業務場景下這樣的處理方式是不能接受的。由於系統的使用者提出了新的需求類似平時的SSO處理機制,大概無任何操作一二十分鍾就提示需要再次登錄,這樣的要求是合理的,之前也沒有太注意這個方面的時間,所以就需要回過頭來研究Flask-Login的session失效時間和設置問題。以前的登錄部分代碼:
1 @app.route('/login', methods=['GET', 'POST']) 2 def login(): 3 if request.method == 'GET': 4 return render_template('login.html') 5 6 username = request.form['username'] 7 password = request.form['password'] 8 user = User.get_user(username, password) 9 if not user: 10 flash('Username or Password is invalid.', 'error') 11 return redirect(url_for('.login')) 12 login_user(user) 13 14 # flash('Logged in successfully', "info") 15 16 return render_template('index.html')
其中的User是models.py中定義的class,可以用於驗證用戶的合法性。在views部分通過@login_required控制,這樣可以成功驗證用戶並跳轉到相應頁面,但是之前提到的session失效問題默認是很長時間而且一旦關閉瀏覽器即失效。那么如何設置能夠實現制定時間內session失效,比如10minutes,查了一下文檔竟然沒發現說到這個問題,比如這個網站:http://www.pythondoc.com/flask-login/應該是正規的文檔吧,接着查一些論壇,很多人討論這個問題,有說設置REMEMBER_COOKIE_DURATION這個參數的,但是仔細看了這個參數和要解決的問題不是一個問題,接着就想到去stackoverflow上查一下吧,就搜索了一下關鍵詞,找了好幾個問答,其中有說到參數permanent_session_lifetime,
我覺得應該是這個差不多了,接着就這個關鍵詞再次搜索,果然發現了一些很有參考價值問答,其中還提到session.permanent = True這個參數,於是在代碼里進行設置:
from flask import session from datetime import timedelta session.permanent = True app.permanent_session_lifetime = timedelta(minutes=10)
其中兩個參數意義也比較好理解,第一個為設置session為永久的,第二個再來制定具體時間
但是,關鍵是但是測試了半天貌似不起作用,又查了半天中文的一些論壇,不知原因何在,然后又是在stackoverflow上有人說這個設置不能放在request外面,要放在request里面才能生效,比如這樣:
1 from flask import session 2 from datetime import timedelta 3 4 @app.route('/login', methods=['GET', 'POST']) 5 def login(): 6 if request.method == 'GET': 7 return render_template('login.html') 8 9 username = request.form['username'] 10 password = request.form['password'] 11 user = User.get_user(username, password) 12 if not user: 13 flash('Username or Password is invalid.', 'error') 14 return redirect(url_for('.login')) 15 login_user(user) 16 session.permanent = True 17 app.permanent_session_lifetime = timedelta(minutes=10) 18 # flash('Logged in successfully', "info") 19 20 return render_template('index.html')
再去測試,已經可以成功按設置的時間來提示登錄了。
這個問題也許對於一些人來不算問題,但是從我自己解決這個問題來看,目前我們的一些文檔,問答還是有很多欠缺的地方,論壇上往往對一個問題互相轉載,很少有獨立的思考和實踐的代碼sample讓初學者參考,在此再次推薦推薦大家一個問答網站:stackoverflow,相信很多人也都在用這個,能夠得到很多有價值的問答,尤其是在國內還不是用的特別廣泛的技術。
對於這個問題,目前也是能使用的階段,也沒有再去研究Flask-Login的一些原理,對於技術只有實踐了你才有可能真正掌握,或者只能停留在理論階段,希望以后有機會再深入研究實踐一下。
