Flask用户认证的详细指南

852 阅读5分钟

编码员们,你们好!

本文介绍了如何使用Flask-LoginBootstrap 5 来编码一个简单的Flask用户认证系统。能够将一个用户与另一个用户区分开来的网络应用在功能和控制方面可以得到很大的改善。例如,我们可以将项目结构分成公共/私人部分,还可以授权用户根据他们的档案执行特定的行动。对于新手来说,Flask是一个在Python基础上精心制作的轻量级框架,用于任何类型的项目和网络应用:简单的网站、API、微服务,甚至是复杂的电子商务解决方案。

谢谢你的阅读!- 内容由App Generator提供:

  • 第1节- 项目的总体情况
  • 2节 - 什么是Flask
  • 第3节 - Flask-Login库
  • 4节 - 项目的代码
  • 5节- 登录、注销、注册路线
  • 6节- 完整的源代码(发布在Github上)

Flask User Authentication - Animated Presentation.

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 - Open-source Python Framework.

安装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用户认证- 源代码

Flask User Authentication - Animated Presentation.

谢谢你的阅读!更多资源,请访问: