其实我写这个代码分析,主要的目的就是梳理一下,各个代码块之间是如何联系的,如何联动,如何工作,最终形成几个跳转的页面.
上一篇博文里说了密码加密,登录密码验证的代码,这篇博文我分享一下登陆模型,登录表单,登录路由保护,登出等代码块,最后会给出登录认证代码的清晰的思路,有错误的地方,欢迎指正.
FLASK-Login这个扩展能很好的提供登录模型,先安装扩展.由于我是在ubuntu中建的虚拟环境(venv),所以代码前是虚拟环境的标识.多说一句,你的flask是python2的环境,那么用pip安装就好了,我习惯了python3.
(venv) $ pip3 install flask-login
接下来写user模型app/models.py,之前博文中产生密码散列值的模型也在这个文件中编写.UserMixin是flask_login扩展中一个类能实现扩展的调用使用.
from flask_login import UserMixin
class User(UserMixin, db.Model):
__tablename__ = 'users' #指定为'user'
id = db.Column(db.Integer, primary_key = True)#把表中的id作为主键值,整型数据
email = db.Column(db.String(64), unique=True, index=True)
username = db.Column(db.String(64), unique=True, index=True)#把email,username作为键值,并不允许重复,类型均为string
password_hash = db.Column(db.String(128))#把密码的散列值作为键值,以便验证密码时访问.
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))#把表role中的id列添加到users表的被称为外键的role_id的列中,建立了两个表的联系.
接下来初始化flask-login,app/_init_.py
from flask_login import LoginManager
login_manager = LoginManager()#启动程序对象
login_manager.session_protection = 'strong'#把会话安全等级设为最高,这样flask-login就会记录客户端IP的地址和浏览器的代理地址,检测到异常就会自动退出登录.
login_manager.login_view = 'auth.login'#把登录页面作为启动的路由
def create_app(config_name):
# ...
login_manager.init_app(app)
#配置信息
flask-login要求程序实现一个回调函数,返回接收到的unicode形式的用户对象如果没有找到就返回none,程序如下.一般放在程序的末尾,app/models.py
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))#用户查询函数来接收用户标识符id
还要做的一件事是保护路由,确保当未认证的用户访问登录路由时,会被拦截.其实在程序中判断用户认证时已经将未认证的用户的请求拦截,并发送到了登录界面,可以看上一篇博文中,验证用户时的设置.下面是可以实现该功能的代码,并不是整个工程程序块中的代码
from flask_login import login_required
@app.route('/secret')
@login_required
def secret():
return 'Only authenticated users are allowed!'
前面就是一些重要的支线任务了,现在看主线任务,添加登录表单.
添加登录表单包含email,password,remember_me,submit等字段,并给出了对应的类型以及格式,required函数给出类型要求,password类型的数据那么输入时是不可见的,email类型的数据输入时必须满足邮件格式.
from flask.ext.wtf import Form
from wtforms import StringField, PasswordField, BooleanField, SubmitField
from wtforms.validators import Required, Length, Email
class LoginForm(Form):
email = StringField('Email', validators=[Required(), Length(1, 64),Email()])
password = PasswordField('Password', validators=[Required()])
remember_me = BooleanField('Keep me logged in')
submit = SubmitField('Log In')
表单写完后,需要模板渲染后显示为页面,用在博文一中提到的wtf.quick_form()来渲染,这个宏在login.html文件中 {{ wtf.quick_form(form) }}.然后登录时用户验证部分上一篇博文中有说到.