flask_login模块
flask-login为flask提供了用户会话管理。他处理了日常的登入,登出并且长时间记住用户的会话。
-
在会话中存储当前活跃的用户ID让你能够自由地登入和登出。
-
让你限制登入或登出,用户可以访问的试图。
-
处理让人棘手的记住我功能。
-
帮助你保护用户会话免遭cookie被盗的牵连。
-
.可以与以后可能使用的flask-principal或其他认证扩展集成。
一、配置你的应用
对一个使用flask-login的应用最重要的一部分是loginmanager类。
login_manager = LoginManager()
login_manager.init_app(app)
二、他是如何工作的
必须提供一个user_loader回调。
@login_manager.user_loader
def load_user(userid):
return User.get(userid)
接受一个用户的unicodeID作为参数,并且返回响应的用户对象。
如果ID无效的话,他应该返回None。
我的理解是:参数user_loader
标记的函数虽然在程序中没有显示调用,但是每次程序每次访问login_required
标注的函数,都会从session中通过user_id
重新加载当前用户对象。
三、你的用户类
你用来标识用户的类需要实现这些属性和方法:
四个方法:
is_authenticated()
、is_active()
、is_anonymous()
、get_id()
-
is_authenticated()
当用户通过验证时,也即提供有效证明是返回true。 -
is_active()
可以直接返回true。 -
is_anonymous()
如果是匿名用户,返回true。真实用户返回False。 -
get_id()
返回一个能唯一识别用户的,并能用于user_loader回调中加载用户的Unicode ID。
要简便的实现用户类,可以从UserMixin继承,他提供了对所有这些方法的默认实现。
四、login示例
一旦用户通过验证,然后把这个对象传给login_user
,如果登录信息正确则跳转到指定URL导航界面。在此必须编写回调函数load_user()
,用于返回通过id获取数据库的用户对象,在每次访问带有login_required
装饰器的试图函数时都会执行回调函数load_user()
。
@app.route('/login',methods=['GET','POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
login_user(user)
flask.flash('Logged in successfully.')
@login_manager.user_loader
def load_user(id):
return user_dal.User_Dal.load_user_byid(id)
这里必须验证next参数,如果不验证,你的应用会收到重定向攻击。
next = flask.request.args.get('next')
if not next_is_valid(next):
return flask.abort(400)
return flask.redirct(next or flask.url_for('index'))
return flask.render_template('login.html', form=form)
需要用户登入的视图可以用login_required
装饰器来装饰。
@app.route('/settings')
@login_required
def settings():
pass
当用户需要登出时,使用logout_user方法。
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(somewhere)
他们会被登出,且他们会话产生的任何cookie都会被清理干净。此时再访问@login_required标注的函数,则会弹出401错误。见下👇
五、定制登入过程
默认情况下,当未登录的用户尝试访问一个login_required装饰的视图,flask-login会闪现一条消息并且重定向到登录视图。
如果未设置登录视图,他将会以401错误退出。
登录视图的名称可以通过LoginManager.login_view
语句设置成:
login_manager.login_view = 'login_name'
这个login_name
是你设置的登录的路由
默认的闪现消息是Please log in to access this page
注意:如果要获得此条闪现信息,可以在上两行提到的login_name
路由所在的函数通过get_flashed_messages()
获得。
当然你也可以自定义该信息,请设置login_message
。
login_manager.login_message = u'please log in'
要自定义消息分类,请设置login_message_category
。
login_manager.login_message_category = 'info'
当重定向到登入视图,他的请求字符串中会有一个next变量,其值为用户之前访问的页面。
六、使用request loader定制登录
有时你想要不使用cookies情况下登录用户,比如使用http头或者一个作为查询参数的api密钥。
这种情况下应该是用request_loader
回调。
七、匿名用户
默认情况下,当一个用户没有真正的登录,current_user被设置成一个AnonymousUserMixin对象。
is_active is_authenticated
的值为False
is_anonymous
的值为true
get_id
返回None
八、记住我(remember功能)
记住我的功能很难实现。但是flask-login几乎透明的实现它。
只要把remember=True
传递给login_user
。
一个cookie将会存储在用户计算机中,如果用户会话中没有用户ID的话,flask-login会自动地从cookie中恢复用户ID。
这里cookie是防篡改的。
该层功能是被自动实现的。
九、会话保护
当上述特性保护记住我令牌免遭cookie窃取时,会话cookie依然是脆弱的。
session_protection的值为basic或者strong。禁用时应设置为None。
默认时被激活为basic模式。