Flask框架的学习指南之用户登录管理
继续flask的学习之旅。今天介绍flask的登陆管理模块,还记得上一篇中的blog小项目么,登录是咱们自己写的验证代码,大概有以下几个步骤:
1、在登录框中输入用户名和密码
2、flaskview函数获取用户密码,然后到数据库中查询该用户信息,进行匹配
3、如果成功,就写入session中,重定向到首页
4、如果对于特定视图,必须要登录才能访问,那么需要在每个视图函数验证session里是否存在该用户。
今天继续改造blog项目,介绍的flask-login模块就是替我们来搞定这些业务相关度较少的公用功能,它可以帮助我们:
在会话中存储当前活跃的用户ID,让你能够自由地登入和登出。
让你限制登入(或者登出)用户可以访问的视图。
处理让人棘手的“记住我”功能。
帮助你保护用户会话免遭cookie被盗的牵连。
可以与以后可能使用的Flask-Principal或其它认证扩展集成。
一、如何使用flask-login模块?
1、安装flask-login
E:\workdir\dct-server-5055187\src>pipinstallflask-login
2、使用flask-login
2.1) 在/blog2/__init__.py添加:
#引用包 fromflask.ext.loginimportLoginManager #登陆管理 #声明login对象 login_manager=LoginManager() #初始化绑定到应用 login_manager.init_app(app) #声明默认视图函数为login,当我们进行@require_login时,如果没登陆会自动跳到该视图函数处理 login_manager.login_view="login" #当登陆成功后,该函数会自动从会话中存储的用户ID重新加载用户对象。它应该接受一个用户的unicodeID作为参数,并且返回相应的用户对象。 @login_manager.user_loader defload_user(userid): returnUser.query.get(int(userid))
2.2)修改User模型(红色部分为新增代码)
fromflask.ext.loginimportUserMixin fromblog2importdb classUser(db.Model,UserMixin): __tablename__='b_user' id=db.Column(db.Integer,primary_key=True) username=db.Column(db.String(10),unique=True) password=db.Column(db.String(16)) def__init__(self,username,password): self.username=username self.password=password def__repr__(self): return'<User%r>'%self.username
该用户类必须实现以下几个方法:
is_authenticated
当用户通过验证时,也即提供有效证明时返回True(只有通过验证的用户会满足login_required的条件。)
is_active
如果这是一个活动用户且通过验证,账户也已激活,未被停用,也不符合任何你的应用拒绝一个账号的条件,返回True。不活动的账号可能不会登入(当然,是在没被强制的情况下)。
is_anonymous
如果是一个匿名用户,返回True。(真实用户应返回False。)
get_id()
返回一个能唯一识别用户的,并能用于从user_loader回调中加载用户的unicode。注意着必须是一个unicode——如果ID原本是一个int或其它类型,你需要把它转换为unicode。
要简便地实现用户类,你可以从UserMixin继承,它提供了对所有这些方法的默认实现。我们这里使用UserMixin实现。
2.3)修改view函数(红色部分为新增)
fromflask.ext.loginimportlogin_required,login_user,logout_user fromblog2.model.UserimportUser fromblog2.model.CategoryimportCategory importos fromblog2importapp,db fromflaskimportrequest,render_template,flash,abort,url_for,redirect,session,Flask,g @app.route('/') @login_required defshow_entries(): categorys=Category.query.all() returnrender_template('show_entries.html',entries=categorys) @app.route('/add',methods=['POST']) @login_required defadd_entry(): #—————————————————————————————————————————————— #第一版登陆方式 #ifnotsession.get('logged_in'): #abort(401) #—————————————————————————————————————————————— title=request.form['title'] content=request.form['text'] category=Category(title,content) db.session.add(category) db.session.commit() flash('Newentrywassuccessfullyposted') returnredirect(url_for('show_entries')) @app.route('/login',methods=['GET','POST']) deflogin(): error=None ifrequest.method=='POST': user=User.query.filter_by(username=request.form['username']).first() #—————————————————————————————————————————————————————————————————————————— #第一版登陆方式 #passwd=User.query.filter_by(password=request.form['password']).first() # #ifuserisNone: #error='Invalidusername' #elifpasswdisNone: #error='Invalidpassword' #else: #session['logged_in']=True #flash('Youwereloggedin') #returnredirect(url_for('show_entries')) #—————————————————————————————————————————————————————————————————————————— login_user(user) flash('Loggedinsuccessfully.') returnredirect(url_for('show_entries')) returnrender_template('login.html',error=error) @app.route('/logout') @login_required deflogout(): #—————————————————————————————————————————————— #第一版登出方式 #session.pop('logged_in',None) #—————————————————————————————————————————————— logout_user() flash('Youwereloggedout') returnredirect(url_for('show_entries'))
通过flask-login管理登陆,代码非常简洁简单:
@login_required:该装饰器放到需要登陆才能访问的视图上,如果没有登陆访问有限制的视图就会跳到login页面,由__init__.py中login_manager.login_view="login"控制
login_user(user):传入一个user对象进行登陆验证,正确返回true,否则返回false
logout_user():登出函数,清空session中用户信息
2.4)模板中引用用户
{%ifcurrent_user.is_authenticated()%} Hi{{current_user.name}}! {%endif%}
将之前layout.html和show_entries.html模板中判断用户是否登陆方式改为flask-login中的方式:
{%ifnotcurrent_user.is_authenticated()%}
current_user值:在用户没有登陆时,值为<flask_login.AnonymousUserMixinobjectat0x0000000003DCF550>,也就是匿名用户
用户登陆后,值为<Useru'admin'>
当然,用户登陆还可以根据实际情况自己定制,具体不在一一详述。
【参考文档】
Flask-Login中文版:http://www.pythondoc.com/flask-login/#id1
Flask-Login英文版:http://flask-login.readthedocs.io/en/latest/