内容简介:原文:声明:原创不易,未经许可,不得转载今天的课程主要给大家介绍一款非常好用的Flask插件—Flask_Login,该插件主要用来管理用户的登陆状态。通过今天的学习,你将学会如何维护用户的登录、登出状态。教程中的代码都会托管到github上,猫姐一再强调,在学习本课内容时一定要亲自动手实现代码,遇到问题再到github上查看代码,如果实在不知道如何解决,可以在日志下方留言。
原文: http://www.catonlinepy.tech/
声明:原创不易,未经许可,不得转载
1. 你将学会什么
今天的课程主要给大家介绍一款非常好用的Flask插件—Flask_Login,该插件主要用来管理用户的登陆状态。通过今天的学习,你将学会如何维护用户的登录、登出状态。教程中的代码都会托管到github上,猫姐一再强调,在学习本课内容时一定要亲自动手实现代码,遇到问题再到github上查看代码,如果实在不知道如何解决,可以在日志下方留言。
2. 使用Flask_Login
2.1 项目目录结构的创建
当用户登录某个应用时,应用需要记住该用户的登陆状态。在开发过程中,如果我们自己造轮子,去实现管理用户登录状态的代码,就会浪费大量时间。但现实中,我们往往需要聚焦在业务上的开发,Flask_Login就是前人造好的管理用户登录状态的轮子,并且这个插件上手起来毫无难度。照旧,在正式使用Flask_Login插件之前,还是先建立今天的项目目录,如下:
# 进入到虚拟环境目录,激活虚拟环境 maojie@Thinkpad:~/flask-plan/$ source miao_venv/bin/activate # 到flask-course-primary目录下创建第五天的课程day5目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ mkdir day5 # 进入day5目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ cd day5 # 新建userauth_demo目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5$ mkdir userauth_demo # 进入到userauth_demo目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5$ cd userauth_demo/ # 在userauth_demo目录中新建__init__.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ touch __init__.py # 在userauth_demo包中新建routes.py路由文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ touch routes.py # 在userauth_demo包中新建models.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ touch models.py # 在userauth_demo包中新建forms.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ touch forms.py # 在userauth_demo包中新建config.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ touch config.py # 在userauth_demo包中新建templates目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ mkdir templates # 进入到templates目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo$ cd templates/ # 在templates目录中新建layout.html (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo/templates$ touch layout.html # 在templates目录中新建login.html (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo/templates$ touch login.html # 在templates目录中新建register.html (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo/templates$ touch register.html # 在templates目录中新建index.html (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/userauth_demo/templates$ touch index.html # 在day5目录下新建run.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5/$ touch run.py
最终,我们得到今天项目的目录结构如下(使用tree命令得到):
(miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ tree day5 day5 ├── run.py └── userauth_demo ├── config.py ├── database.db ├── forms.py ├── __init__.py ├── models.py ├── routes.py └── templates ├── index.html ├── layout.html ├── login.html └── register.html
安装Flask_Login插件的方式与其它插件的安装方式一样,使用pip命令,如下:
# 注意,一定要在虚拟环境中 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day5$ pip install Flask_Login
然后在__init__.py文件中对Flask_Login进行配置,大家首先把第4天__init__.py文件中的内容复制过来,然后添加如下代码:
# ... from flask_login import LoginManager app = Flask(__name__) # ... login_manager = LoginManager(app) # ...
2.2 准备用户的登陆模型
在正式创建登录模型之前,我们先介绍一下config.py文件,该文件的作用存放与应用相关的所有配置信息。在之前的教程中,我们直接将配置信息写到了__init__.py文件中,这样不利于复杂 web应用程序的开发管理,后续章节的配置内容都将会放到config.py文件中,配置代码如下所示:
# config.py文件中的内容 import os basedir = os.path.abspath(os.path.dirname(__file__)) class Config(object): SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'database.db') # 使用表单,对Flask_WTF进行配置 SECRET_KEY = 'miaojie is great!'
__init__.py文件只需添加如下代码便可导入config.py文件中所有配置信息:
# __init__.py文件中的内容 # .. from userauth_demo.config import Config app = Flask(__name__) app.config.from_object(Config) # ..
建立用户的登陆模型是创建数据库表的过程,在第4课中,我们谈到了如何去建立用户模型,这里不再详细讲解,直接使用即可。要想使用Flask_Login插件,在模型中需要实现下面几个方法(函数),如下:
方法 说明
is_authenticated() 如果用户已经登录,必须返回 True ,否则返回 False
is_active() 如果允许用户登录,必须返回 True ,否则返回 False 。如果要禁用账户,可以返回 False
is_anonymous() 对普通用户必须返回 False
get_id() 必须返回用户的唯一标识符,使用 Unicode 编码字符串
但是Flask_Login提供了一个更简便的方法—UserMixin类,开发人员只需要让User类继承UserMixin类即可完成对User表的登录管理,UserMixin包含这4个方法的默认实现(因此上面这张表的内容大家完全不用关心)。由于后面的代码会越来越复杂,为了使代码更易管理,所有建立数据库模型的代码将放在models.py文件中。如下所示,在models.py中建立User模型:
# 在models.py文件中的内容 #!coding:utf8 from userauth_demo import db from flask_login import UserMixin # User继承UserMixin类 class User(UserMixin, db.Model): __tablename__ = 'user' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(20), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) password = db.Column(db.String(60), nullable=False) def __repr__(self): return f"User('{self.username}','{self.email}','{self.password}')" # 在这个模型中,还添加了email字段,因为在用户登陆的时候,不仅可以输入用户名登陆,也可以输入email登陆
第4课中已经讲了数据库的迁移,大家可以直接按照第4课的5.3小结内容进行操作即可,同样在操作之前,需要设置环境变量,环境变量在第1课的3节最后已经讲过如何设置了。
最后,Flask_Login插件要求程序有一个回调函数,可以加载指定ID的用户。在models.py文件中增加如下代码:
# .. # 从userauth_demo包中导入login_manager实例 from userauth_demo import login_manager # 回调函数 @login_manager.user_loader def load_user(user_id): # print调试时用 #print(user_id) return User.query.get(int(user_id)) # ..
2.3 添加登陆表单
表单在第三课中已经讲到过,现在将表单直接拿过来用,所有建立表单的代码都将放在forms.py文件中,在forms.py文件中添加登陆表单内容:
# 在forms.py文件中的内容 from flask_wtf import FlaskForm from wtforms.fields.html5 import EmailField from wtforms import PasswordField, BooleanField, SubmitField from wtforms.validators import DataRequired, Length class LoginForm(FlaskForm): # 表单包括邮箱,密码和是否记住密码及一个提交按钮 email = EmailField(u'邮箱', validators=[DataRequired(), Length(min=2, max=20)]) password = PasswordField(u'密码', validators=[DataRequired()]) remember = BooleanField(u'记住我') submit = SubmitField(u'登陆')
在表单中email字段使用了WTForms提供的Length()验证函数,确保用户输入的email长度在2到20的范围内,PasswordField可使Jinja2生成type="password"的<input>标签;BooleanField可使Jinjia2生成true或false的可选框;SubmiteField可使Jinjia2生成type="submit"的<input>标签。
2.4 表单的渲染
在第二课中已经讲到过模板的继承概念,今天的课程会继续用到这一概念,这里就不重复描述了(大家如果不清楚,可回去再看看第2天的课程)。在templates/layout.html中输入如下html代码:
<!-- layou.html文件中的内容 --> <html> <head> {% if title %} <title>{{ title }}-喵星在线</title> {% else %} <title>喵星在线</title> {% endif %} </head> <header> <div> <a href="/">主页</a> <a href="/login">登陆</a> </div> </header> <body> <!-- 渲染flash消息 --> {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %} <div class="alert alert-{{ category }}"> {{ message }} </div> {% endfor %} {% endif %} {% endwith %} {% block content %} {% endblock %} </body> </html>
然后通过子模板index.html继承基模板layout.html,在templates/index.html中输入如下代码:
<!-- index.html文件中的内容 --> {% extends "layout.html" %} <!--重新填写content块的内容--> {% block content %} <h1>你好,喵星在线!</h1> {% endblock %}
此外,我们还需要一个登录页面,让我们可以输入邮箱和密码,在templates/login.html中输入如下代码:
<!-- login.html文件中的内容 --> {% extends "layout.html" %} {% block content %} <h2>登陆</h2> <form action="" method="post"> {{html_form.hidden_tag() }} <div> {{ html_form.email.label }}<br /> {{ html_form.email() }} {% if html_form.email.errors %} <div> {% for error in html_form.email.errors %} <span>{{ error }}</span> {% endfor %} </div> {% endif %} </div> <div> {{ html_form.password.label }}<br /> {{ html_form.password() }} </div> <div> {{ html_form.remember.label }} {{ html_form.remember() }} </div> <div> {{ html_form.submit() }} </div> </form> {% endblock content %}
上面已经完成login.html页面前台form表单的显示(渲染)工作,这时就需要在视图函数中(python文件)将代表表单的类传递到前端模板文件(html文件)中,下面在routes.py中完成视图函数的编写:
# routes.py文件中的内容 #!coding:utf8 # 文件中有中文,必须在代码最前面注明utf8编码,否则程序拉起时会报错 from flask import render_template, redirect, url_for, flash from userauth_demo import app from userauth_demo.forms import LoginForm # 从userauth_demo.forms中导入LoginForm类 from flask_login import current_user from userauth_demo.models import User # 添加视图函数渲染主页内容 @app.route('/') def index(): return render_template('index.html', title='第五天') # 在视图函数中将form表单传到前端html文件中去 @app.route('/login', method=['GET','POST']) def login(): if current_user.is_authenticated: return redirect(url_for('index')) # 对类LoginForm的实例 form = LoginForm() if form.validate_on_submit(): if form.email.data == '424277539@qq.com' and form.password.data == 'miaojie': flash('你已经登陆成功', 'success') # flash消息的渲染 return redirect(url_for('index')) # 如果登陆成功,则重定向到主页 # 将视图函数中的变量form传到模板login.html文件中去 return render_template('login.html', title='第五天', html_form=form)
current_user是由Flask_Login导入的,它在视图函数和模板中可以直接使用。它表示的是当前登陆的用户,如果用户未登陆,则表示用户是匿名用户,is_authenticated则会返回False。当在表单中填好内容后,点击提交按钮时,validate_on_submit发送的是post请求,if判断语句中填入的是假数据,因为数据还没有写入到数据库,无法使用数据库将用户的邮箱和密码读取出来,后面会讲到用户的注册,将用户的信息写到数据库中。
在run.py文件中输入如下代码,将web程序拉起:
from userauth_demo import app # 从userauth_demo包中导入app实例 if __name__ == "__main__": app.run(debug=True, port=5005) # app实例调用自己的run函数 # 在app.run里面可以指定端口号,当下次再运行python run.py时,可能提示端口号被占用,此时,可以修改run.py文件中的端口号
现在,所有代码已编写完成,通过python run.py将web程序拉起,开始验证结果,在浏览器中输入 http://127.0.0.1 :5005/login,效果图如下所示:
在登陆表单中输入用户名及密码,点提交按钮后的效果图:
3. 上篇完,未完待续...
由于第5天的课程涉及登录和注册两方面的知识,内容比较多,因此猫姐将第5天的课程分为上、下两篇进行讲解,这里我们完成上篇登录功能的实现,下篇我们将接着讲解注册功能,以及注册后登录功能的实现。
以上所述就是小编给大家介绍的《第5天上篇:在Flask应用中使用用户认证—Flask_Login》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 思科推出最新认证考纲 将首先应用于CCIE认证
- 思科推出最新认证考纲 将首先应用于CCIE认证
- 物联网应用认证:TPM2.0助力
- 社团链应用场景深度解析之----零知识身份认证
- 安卓系统获FIDO2认证,可用指纹登录应用和网站
- 人工智能在电信实名认证中的关键技术及应用
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
XML、JSON 在线转换
在线XML、JSON转换工具
正则表达式在线测试
正则表达式在线测试