如何基于服务器会话中的user_id实现Flask API用户级限流?
按用户ID实现Flask API限流的修改方案
核心思路
替换默认的IP限流标识,改为从服务器会话中提取user_id作为限流key;未登录用户可 fallback 到IP限流(按需调整)。
步骤1:自定义限流Key函数
编写函数优先从session获取用户ID,不存在则使用IP作为备选,同时给用户ID添加前缀避免与IP标识冲突:
from flask import session from flask_limiter.util import get_remote_address def get_user_identifier(): # 从服务器会话中读取用户ID user_id = session.get("user_id") # 已登录用户用带前缀的user_id作为限流key,未登录用户 fallback 到IP return f"user:{user_id}" if user_id else get_remote_address()
步骤2:全局生效的修改(所有路由按用户限流)
直接替换Limiter初始化时的key_func,让所有路由默认使用用户ID作为限流标识:
from flask_limiter import Limiter limiter = Limiter( key_func=get_user_identifier, # 替换为自定义的用户标识函数 storage_uri="redis://localhost:6379", strategy="moving-window" )
步骤3:局部生效的修改(仅目标路由按用户限流)
如果只想让/api/submit-code路由按用户限流,保留全局IP限流规则,只需在该路由的limit装饰器中指定key_func参数:
@api.route('/api/submit-code') @limiter.limit('3 per minute', key_func=get_user_identifier) def submit_code(): user_id = session.get("user_id") if not user_id: return jsonify({"error": "Unauthorized"}), 401 # 后续业务逻辑...
注意事项
- 确保Flask应用已配置
SECRET_KEY,否则服务器会话无法正常读取user_id; - 若不需要对未登录用户限流,可在
get_user_identifier中抛出异常,但需配合视图层的权限检查提前拦截未登录请求; - 给用户ID添加
user:前缀,能避免用户ID与IP地址数值重复时的标识冲突问题。
内容的提问来源于stack exchange,提问作者Sam R
相关产品推荐
相关产品推荐

