跳到主要内容
Flask 实战:从环境搭建到鉴权中间件 | 极客日志
Python
Flask 实战:从环境搭建到鉴权中间件 Flask 轻量级 Python Web 框架,基于 Werkzeug 和 Jinja2。内容涵盖环境搭建、项目结构配置、蓝图与工厂模式、Session 及 JWT 认证实现、RBAC 权限控制以及自定义 WSGI 中间件。通过实际代码示例讲解 Gunicorn 部署与日志监控,适合构建 RESTful API 或微服务架构。重点在于灵活配置与安全鉴权的落地实践。
热情 发布于 2026/3/16 更新于 2026/4/25 1 浏览Flask 框架实战指南
1. Flask 框架概述
1.1 什么是 Flask?
Flask 是一个轻量级的 Python Web 框架,基于 Werkzeug WSGI 工具箱和 Jinja2 模板引擎构建。它的设计哲学是可扩展 和灵活 ,不强制特定的项目结构或依赖组件。这意味着开发者可以根据实际需求自由选择数据库、认证方式等组件。
与 Django 等'全能型'框架不同,Flask 遵循'按需配置'原则。它的'微框架'并非功能欠缺,而是核心保持简单,允许开发者构建从小型应用到大型复杂系统的应用程序。
1.2 Flask 的核心特性
轻量级且简单 :代码库小巧,API 简洁,学习曲线平缓。
灵活性高 :不强制使用特定项目结构或库。
扩展性强 :拥有丰富的扩展生态系统(如数据库集成、表单验证)。
Jinja2 模板引擎 :支持模板继承、自动 HTML 转义。
开发服务器和调试器 :内置工具便于开发和调试。
RESTful 请求分发 :适合构建 Web API。
1.3 Flask 与 Django 的对比
特性 Flask Django 设计哲学 微框架,简单核心,高度可扩展 全能型框架,内置大量功能 学习曲线 平缓,易于入门 较陡峭,概念较多 灵活性 高,可自由选择组件 较低,遵循'约定优于配置' 数据库支持 需通过扩展添加 内置 ORM 管理后台 需扩展 内置
1.4 适用场景
RESTful API 开发 :轻量级特性使其成为构建 API 的理想选择。
微服务架构 :适合作为微服务中的单个服务组件。
原型开发 :快速构建概念验证。
嵌入式 Web 服务 :为设备提供界面。
2. Flask 基本使用
2.1 安装与环境配置
推荐使用 Python 3.6 或更高版本。虚拟环境是最佳实践,用于隔离项目依赖。
创建虚拟环境
python -m venv my_flask_env
安装 Flask
pip install flask
安装后会自动包含 Werkzeug、Jinja2、itsdangerous 和 click 等依赖。
验证安装 from flask import Flask
app = Flask(__name__)
@app.route('/' )
def hello ():
return 'Hello, Flask!'
if __name__ == '__main__' :
app.run()
运行 python app.py,访问 http://localhost:5000 即可看到结果。
2.2 基本程序结构 一个基本的 Flask 应用包含初始化实例、定义路由和启动服务器。
初始化应用实例 from flask import Flask
app = Flask(__name__)
__name__ 参数帮助 Flask 确定资源文件位置。
定义路由和视图函数 @app.route('/' )
def index ():
return 'Home Page'
@app.route('/user/<username>' )
def show_user (username ):
return f'User: {username} '
变量部分用 <variable_name> 表示,会作为参数传递。
启动开发服务器 if __name__ == '__main__' :
app.run(debug=True , host='0.0.0.0' , port=5000 )
debug=True 启用调试模式,代码修改后自动重载。
2.3 核心组件详解
路由系统 Flask 支持多种路由定义方式,包括变量类型限制:
@app.route('/post/<int:post_id>' )
def show_post (post_id ):
return f'Post: {post_id} '
@app.route('/login' , methods=['GET' , 'POST' ] )
def login ():
if request.method == 'POST' :
return do_login()
return show_login_form()
支持的类型包括 string, int, float, path, uuid。
请求对象 request 对象包含所有 incoming 数据:
from flask import request
@app.route('/login' , methods=['POST' ] )
def login ():
username = request.form['username' ]
password = request.form['password' ]
page = request.args.get('page' , 1 , type =int )
if request.is_json:
data = request.get_json()
响应对象 from flask import make_response, jsonify
@app.route('/json' )
def json_data ():
return jsonify({'name' : 'John' , 'age' : 30 })
@app.route('/custom' )
def custom_response ():
response = make_response('Custom Response' )
response.headers['X-Custom-Header' ] = 'Value'
response.status_code = 201
return response
模板渲染 使用 Jinja2 引擎,模板存放在 templates 文件夹:
from flask import render_template
@app.route('/hello/<name>' )
def hello (name ):
return render_template('hello.html' , name=name)
模板中使用 {{ url_for('static', filename='style.css') }} 生成静态文件链接。
2.4 扩展 Flask 功能 常用扩展包括 Flask-SQLAlchemy(ORM)、Flask-WTF(表单)、Flask-Login(认证)等。安装后通常通过 Extension(app) 或 init_app(app) 初始化。
3. Flask 项目配置
3.1 配置基础 配置通过 app.config 对象管理,类似字典。
直接设置配置值 app.config['DEBUG' ] = True
app.config['SECRET_KEY' ] = 'your-secret-key'
或使用属性语法 app.debug = True。
常用内置配置变量 配置变量 说明 DEBUG启用/禁用调试模式 SECRET_KEY加密签名密钥 SESSION_COOKIE_HTTPONLY禁止 JS 访问会话 cookie PERMANENT_SESSION_LIFETIME永久会话生存期
3.2 配置方法
从 Python 文件加载
DEBUG = True
SECRET_KEY = 'your-secret-key'
app.config.from_pyfile('config.py' )
从对象加载 class Config :
DEBUG = False
SECRET_KEY = 'development-key'
class ProductionConfig (Config ):
DATABASE_URI = 'postgresql://...'
app.config.from_object('configmodule.ProductionConfig' )
多重配置加载策略 app = Flask(__name__)
app.config.from_object('app.config.DefaultConfig' )
env = os.environ.get('FLASK_ENV' , 'development' )
if env == 'production' :
app.config.from_object('app.config.ProductionConfig' )
else :
app.config.from_object('app.config.DevelopmentConfig' )
3.3 大型项目配置
项目结构 flask_project/
├── apps/ # 蓝图模块
├── conf/ # 配置文件
├── middleware/ # 中间件
├── utils/ # 工具类
├── static / # 静态文件
├── templates/ # 模板
├── extensions.py # 扩展配置
├── app.py # 入口文件
└── settings.py # 全局配置
应用工厂模式 def create_app (config=None ):
app = Flask(__name__)
if config is None :
app.config.from_object('settings' )
else :
app.config.from_object(config)
db.init_app(app)
app.register_blueprint(app01)
register_middleware(app)
return app
蓝图 (Blueprint) 使用
from flask import Blueprint
app01 = Blueprint('app01' , __name__, url_prefix='/api/v1/app01' )
app.register_blueprint(app01)
3.4 扩展配置
数据库配置 from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
日志配置 使用 logging.config.dictConfig 配置控制台和文件输出:
import logging.config
LOGGING = {
'version' : 1 ,
'handlers' : {
'console' : {'class' : 'logging.StreamHandler' },
'file' : {'class' : 'logging.handlers.RotatingFileHandler' , 'filename' : 'app.log' }
},
'loggers' : {
'flask_logger' : {'handlers' : ['console' , 'file' ], 'level' : 'INFO' }
}
}
logging.config.dictConfig(LOGGING)
3.5 部署配置
使用 Gunicorn 部署 gunicorn -c gunicorn_config.py app:app
使用 Nginx + uWSGI 部署 uWSGI 配合 Nginx 反向代理,Nginx 负责静态文件和负载均衡,uWSGI 处理应用逻辑。
使用 Supervisor 管理进程 Supervisor 可监控 uWSGI 进程状态,实现自动重启和日志管理。
4. 接口鉴权
4.1 认证与授权基础 认证 (Authentication) 验证用户身份,授权 (Authorization) 确定权限范围。
Session-based 认证 基于服务器存储,登录成功后生成 session_id 存入 Cookie,服务端存储会话数据。
Token-based 认证 基于客户端,通常使用 JWT。登录后返回 Token,后续请求携带 Token,服务端无需存储会话状态。
4.2 Session 认证实现
基本 Session 配置 from flask import Flask, session
import os
app = Flask(__name__)
app.secret_key = os.urandom(24 )
app.config['SESSION_TYPE' ] = 'filesystem'
登录和会话管理 from werkzeug.security import generate_password_hash, check_password_hash
USER_DATA = {"test_user" : generate_password_hash("password123" )}
@app.route('/login' , methods=['POST' ] )
def login ():
data = request.json
username = data.get('username' )
password = data.get('password' )
if username in USER_DATA and check_password_hash(USER_DATA[username], password):
session['username' ] = username
session['logged_in' ] = True
session.permanent = True
return jsonify({"message" : "Login successful" }), 200
return jsonify({"message" : "Invalid credentials" }), 401
使用 Redis 存储 Session from flask_session import Session
import redis
app.config['SESSION_TYPE' ] = 'redis'
app.config['SESSION_REDIS' ] = redis.from_url('redis://localhost:6379' )
Session(app)
4.3 Token 认证 (JWT) 实现
安装和配置 pip install flask-jwt-extended
from flask_jwt_extended import JWTManager
app.config['JWT_SECRET_KEY' ] = 'your-jwt-secret-key'
app.config['JWT_ACCESS_TOKEN_EXPIRES' ] = timedelta(hours=1 )
jwt = JWTManager(app)
实现 JWT 认证 from flask_jwt_extended import create_access_token, jwt_required, get_jwt_identity
@app.route('/login' , methods=['POST' ] )
def login ():
access_token = create_access_token(identity=username)
return jsonify({"access_token" : access_token}), 200
@app.route('/protected' , methods=['GET' ] )
@jwt_required()
def protected ():
current_user = get_jwt_identity()
return jsonify({"message" : f"Welcome {current_user} !" }), 200
高级 JWT 特性 @jwt.additional_claims_loader
def add_claims_to_access_token (identity ):
if identity == "admin" :
return {"is_admin" : True }
return {"is_admin" : False }
4.4 基于角色的访问控制 (RBAC)
实现角色系统 通过数据库模型关联 User、Role 和 Permission:
class User (db.Model):
roles = db.relationship('Role' , secondary=user_roles, backref=db.backref('users' ))
def has_permission (self, permission_name ):
for role in self .roles:
for permission in role.permissions:
if permission.name == permission_name:
return True
return False
基于角色的权限装饰器 from functools import wraps
def permission_required (permission_name ):
def decorator (f ):
@wraps(f )
def decorated_function (*args, **kwargs ):
verify_jwt_in_request()
username = get_jwt_identity()
user = User.query.filter_by(username=username).first()
if not user or not user.has_permission(permission_name):
return jsonify({"message" : "Insufficient permissions" }), 403
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/admin/dashboard' )
@jwt_required()
@permission_required('admin_dashboard' )
def admin_dashboard ():
return jsonify({"message" : "Welcome to admin dashboard" }), 200
4.5 OAuth2 和第三方认证
使用 Authlib 实现 OAuth2 from authlib.integrations.flask_client import OAuth
oauth = OAuth(app)
google = oauth.register(
name='google' ,
client_id='...' ,
client_secret='...' ,
api_base_url='https://www.googleapis.com/oauth2/v1/' ,
client_kwargs={'scope' : 'email profile' }
)
5. 自定义中间件
5.1 中间件概念与原理 中间件在请求处理和响应发送前执行特定代码,用于认证、日志等跨切面关注点。
Flask 中间件工作原理
装饰器模式 :before_request, after_request。
WSGI 中间件 :包装 Flask 应用的 WSGI 应用。
5.2 内置请求钩子
before_request @app.before_request
def before_request ():
print (f"Request received: {request.method} {request.path} " )
if not session.get('user_id' ) and request.endpoint not in ['login' , 'static' ]:
return redirect(url_for('login' ))
after_request @app.after_request
def after_request (response ):
response.headers['X-Frame-Options' ] = 'SAMEORIGIN'
return response
teardown_request @app.teardown_request
def teardown_request (exception=None ):
if hasattr (g, 'db_connection' ):
g.db_connection.close()
5.3 自定义 WSGI 中间件
基本 WSGI 中间件结构 class Middleware :
def __init__ (self, app ):
self .app = app
def __call__ (self, environ, start_response ):
print ('请求前的操作' )
response = self .app(environ, start_response)
print ('请求之后操作' )
return response
app.wsgi_app = Middleware(app.wsgi_app)
5.4 实用中间件实现
日志记录中间件 class RequestLoggingMiddleware :
def __init__ (self, app ):
self .app = app
self .logger = logging.getLogger('request_logger' )
def __call__ (self, environ, start_response ):
start_time = time.time()
def custom_start_response (status, headers, exc_info=None ):
processing_time = time.time() - start_time
self .logger.info(f"{request.remote_addr} - {processing_time:.2 f} s" )
return start_response(status, headers, exc_info)
return self .app(environ, custom_start_response)
跨域中间件 (CORS) class CORSMiddleware :
def __init__ (self, app, origins=None ):
self .app = app
self .origins = origins or ['*' ]
def __call__ (self, environ, start_response ):
if environ['REQUEST_METHOD' ] == 'OPTIONS' :
start_response('200 OK' , [('Access-Control-Allow-Origin' , ', ' .join(self .origins))])
return [b'' ]
def custom_start_response (status, headers, exc_info=None ):
headers.append(('Access-Control-Allow-Origin' , ', ' .join(self .origins)))
return start_response(status, headers, exc_info)
return self .app(environ, custom_start_response)
速率限制中间件 class RateLimitingMiddleware :
def __init__ (self, app, max_requests=100 , time_window=60 ):
self .app = app
self .max_requests = max_requests
self .time_window = time_window
self .requests = defaultdict(list )
def __call__ (self, environ, start_response ):
client_ip = environ.get('REMOTE_ADDR' )
current_time = time.time()
if client_ip in self .requests:
self .requests[client_ip] = [t for t in self .requests[client_ip] if current_time - t < self .time_window]
if len (self .requests[client_ip]) >= self .max_requests:
start_response('429 Too Many Requests' , [('Content-Type' , 'text/plain' )])
return [b'Rate limit exceeded.' ]
self .requests[client_ip].append(current_time)
return self .app(environ, start_response)
5.5 中间件最佳实践
中间件执行顺序 before_request 按注册顺序执行,after_request 按反向顺序 执行。如果某个 before_request 返回了响应,后续 before_request 和视图函数将跳过,但已注册的 after_request 仍会执行。
性能考虑
避免阻塞 I/O 操作。
对昂贵操作使用缓存。
根据路径选择性应用中间件。
6. 总结 本文全面介绍了 Flask 框架的基本使用、项目配置、接口鉴权和自定义中间件的实现。通过深入理解这些概念和技术,您可以构建出健壮、安全且可扩展的 Flask 应用程序。
关键要点回顾
Flask 基础 :轻量级但功能强大,适合各种场景。
项目配置 :支持多种配置源和环境特定配置。
接口鉴权 :实现了 Session 和 JWT 认证,以及 RBAC。
中间件 :通过装饰器和 WSGI 中间件处理跨切面关注点。
最佳实践建议
安全性 :始终使用 HTTPS,妥善管理密钥。
性能 :使用缓存,优化数据库查询。
可维护性 :遵循模块化设计,使用蓝图组织项目。
监控 :记录适当的日志,监控应用性能。
要深入学习 Flask,可进一步探索数据库集成、异步编程、微服务架构及容器化部署。
相关免费在线工具 curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online