编码员们,你们好!
本文介绍了如何使用Flask-Login 和Bootstrap 5 来编码一个简单的Flask用户认证系统。能够将一个用户与另一个用户区分开来的网络应用在功能和控制方面可以得到很大的改善。例如,我们可以将项目结构分成公共/私人部分,还可以授权用户根据他们的档案执行特定的行动。对于新手来说,Flask是一个在Python基础上精心制作的轻量级框架,用于任何类型的项目和网络应用:简单的网站、API、微服务,甚至是复杂的电子商务解决方案。
谢谢你的阅读!- 内容由App Generator提供:
- 第1节- 项目的总体情况
- 第2节 - 什么是Flask
- 第3节 - Flask-Login库
- 第4节 - 项目的代码
- 第5节- 登录、注销、注册路线
- 第6节- 完整的源代码(发布在Github上)
1 - 项目概述
对于简单的演示网站来说,认证可能不是必须的,但对于其他类型的项目来说,则是必须的,因为项目设计需要知道用户何时被认证,以及根据他的凭证(用户名、资料......等)访问哪些资源。我们要编写的项目提供了一个简单的代码库结构,SQLite持久性,以及用Bootstrap 5设计的三个页面(索引、登录、注册)。以下是项目的依赖性。
Flask- 为该应用程序提供动力的框架Flask-Login- 一个用于管理会话的流行库Flask-Bcrypt- 用于密码加密的库Flask-SqlAlchemy- 一个用于访问数据库的流行库
代码库结构
< PROJECT ROOT >
|
|-- app/
| |-- static/
| | |-- <css, JS, images> # CSS files, Javascripts files
| |
| |-- templates/
| | |
| | |-- index.html # Index File
| | |-- login.html # Login Page
| | |-- register.html # Registration Page
| |
| |
| config.py # Provides APP Configuration
| forms.py # Defines Forms (login, register)
| models.py # Defines app models
| views.py # Application Routes
|
|-- requirements.txt
|-- run.py
|
|-- **************************************
2 -什么是Flask
Flask是一个流行的Python框架,旨在使一个项目快速和简单,并能够扩展到复杂的应用程序。Flask可以用来编写从简单的单页网站到API和复杂的电子商务解决方案。
安装Flask的最简单方法是使用PIP,即Python的官方软件包管理器。
$ pip install Flask
在安装过程中,也会安装一组基本的核心依赖项。
Werkzeug实现WSGI,这是应用程序和服务器之间的标准Python接口。Jinja是一种模板语言,用于渲染你的应用程序提供的页面。Click是一个用于编写命令行应用程序的框架。它提供了flask命令并允许添加自定义管理命令。
安装完成后,我们可以打开编辑器,用几行代码编写我们的第一个Flask应用程序。
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, Flask Authentication!'
3 - Flask-Login库
Flask-LoginFlask-Login库,可能是Flask最流行的认证库,它提供了用户会话管理,并处理了登录、注销以及在长时间内记住用户会话的常见任务。
安装Flask-Login
$ pip install flask-login
使用Flask-Login 的应用程序中最重要的部分是LoginManager 类。
login_manager = LoginManager()
一旦Flask应用对象被创建,你可以用一行字来配置它的登录。
login_manager.init_app(app)
它是如何工作的
应用程序需要提供一个user_loader回调。这个回调用于从存储在会话中的用户ID重新加载用户对象。
@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)
上述Flask-Login 的核心原则涵盖了一个简单认证系统的基本实现,我们将在下一节中进行完整的编码。
4 - 编码项目
在我们实际编码功能之前,让我们再次直观地看到结构,并提及最相关的文件。
run.py- 是我们项目的入口点app目录捆绑了我们项目中使用的所有文件和资产app/config.py- 将应用程序的配置隔离在一个地方app/forms.py- 定义了SignIN和SignUP表单app/models.py- 定义了用户表app/views.py- 处理应用程序的路由,如登录、注销和注册
< PROJECT ROOT >
|
|-- app/
| |-- static/
| | |-- <css, JS, images> # CSS files, Javascripts files
| |
| |-- templates/
| | |
| | |-- index.html # Index File
| | |-- login.html # Login Page
| | |-- register.html # Registration Page
| |
| |
| __init__.py # Bundle APP as package
| config.py # Provides APP Configuration
| forms.py # Defines Forms (login, register)
| models.py # Defines app models
| views.py # Application Routes
|
|-- requirements.txt
|-- run.py
|
|-- **************************************
run.py- 源代码
该文件是APP 包的一个超级简单的加载器。
from app import app, db
app/config.py- APP配置
为了方便访问,所有的变量都由一个Config 类来暴露。
class Config():
CSRF_ENABLED = True
# Set up the App SECRET_KEY
SECRET_KEY = config('SECRET_KEY', default='S#perS3crEt_007')
# This will create a file in <app> FOLDER
SQLALCHEMY_DATABASE_URI = 'sqlite:///db.sqlite3'
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY 变量用于加密会话信息,SQLALCHEMY_DATABASE_URI 用于定位SQLite数据库(基本上是一个文件)。
app/forms.py- 登录和注册表格
class LoginForm(FlaskForm):
username = StringField (u'Username' , validators=[DataRequired()])
password = PasswordField(u'Password' , validators=[DataRequired()])
class RegisterForm(FlaskForm):
name = StringField (u'Name' )
username = StringField (u'Username' , validators=[DataRequired()])
password = PasswordField(u'Password' , validators=[DataRequired()])
email = StringField (u'Email' , validators=[DataRequired(), Email()])
登录表单需要一个用户名和一个密码来验证,注册表单有一个额外的电子邮件字段。
app/models.py定义了
Users表
class Users(db.Model, UserMixin):
__tablename__ = 'Users'
id = db.Column(db.Integer, primary_key=True)
user = db.Column(db.String(64), unique = True)
email = db.Column(db.String(120), unique = True)
password = db.Column(db.String(500))
上述所有部分都被捆绑在保存在app目录下的一个特殊文件中来构建Flask应用。"init.py"
app = Flask(__name__) # constructs the Flask app
app.config.from_object('app.config.Config') # injects the configuration
db = SQLAlchemy (app) # flask-sqlalchemy # connects to SQLite DB
lm = LoginManager( ) # flask-loginmanager
lm.init_app(app) # init the login manager
5 - 认证路线
所有的应用路由都由保存在app 目录中的views.py 文件提供。
/register路由--处理新用户的入职工作
该方法实现的伪代码相当简单。
- 如果请求类型是GET,向用户提供注册页面
- 如果用户提交了信息,该方法将进行检查
- 一旦数据被验证,用户密码就会被哈希化。
- 用户对象被创建并保存到数据库中
@app.route('/register', methods=['GET', 'POST'])
def register():
# declare the Registration Form
form = RegisterForm(request.form)
if request.method == 'GET':
return render_template( 'register.html', form=form, msg=msg )
# check if both http method is POST and form is valid on submit
if form.validate_on_submit():
# assign form data to variables
username = request.form.get('username', '', type=str)
password = request.form.get('password', '', type=str)
email = request.form.get('email' , '', type=str)
pw_hash = bc.generate_password_hash(password)
user = Users(username, email, pw_hash)
user.save()
msg = 'User created'
success = True
else:
msg = 'Input error'
return render_template( 'register.html', form=form, msg=msg, success=success )
/login路径- 验证注册用户的身份
@app.route('/login', methods=['GET', 'POST'])
def login():
# Declare the login form
form = LoginForm(request.form)
# Flask message injected into the page, in case of any errors
msg = None
# check if both http method is POST and form is valid on submit
if form.validate_on_submit():
# assign form data to variables
username = request.form.get('username', '', type=str)
password = request.form.get('password', '', type=str)
# filter User out of database through username
user = Users.query.filter_by(user=username).first()
if user:
if bc.check_password_hash(user.password, password):
login_user(user)
return redirect(url_for('index'))
else:
msg = "Wrong password. Please try again."
else:
msg = "Unknown user"
return render_template( 'login.html', form=form, msg=msg )
/logout路径- 删除与用户相关的会话数据
# Logout user
@app.route('/logout')
def logout():
logout_user()
return redirect(url_for('index'))
6 - 完整的源代码
本文解释的源代码可以从Github(MIT许可)下载,用于业余和商业项目。
Flask用户认证- 源代码
谢谢你的阅读!更多资源,请访问:

