在aiogram v3中间件中使用FSM的state.data实现用户认证校验
在aiogram v3中用中间件处理FSM状态实现认证校验
完全可行,这正是中间件的典型应用场景——把重复的校验逻辑抽离出来统一处理,完美契合DRY原则。以下是具体实现方案:
1. 编写认证校验中间件
创建继承自BaseMiddleware的中间件类,在其中完成FSM状态数据的校验:
from aiogram import BaseMiddleware from aiogram.types import Message from aiogram.fsm.context import FSMContext from aiogram.utils.exceptions import SkipHandler class AuthCheckMiddleware(BaseMiddleware): async def __call__(self, handler, event: Message, data: dict): # 从请求上下文获取FSM状态实例 state: FSMContext = data.get("state") if not state: raise SkipHandler() # 读取FSM中的用户数据 state_data = await state.get_data() # 执行认证状态校验 if not state_data.get("isPasswordSetup") or not state_data.get("isPasswordConfirmed"): # 校验不通过时跳过后续handler执行,对应原代码的return 0 # 可选:这里可以添加提示消息,比如 await message.answer("请先完成密码设置与确认") raise SkipHandler() # 校验通过,继续执行原业务handler return await handler(event, data)
2. 注册中间件
根据业务需求,可将中间件注册到特定路由器或全局:
- 注册到特定路由器(仅作用于
menu路由下的handler):
# 假设menu是你的路由器实例 menu.message.middleware(AuthCheckMiddleware())
- 注册为全局中间件(作用于所有消息handler):
from aiogram import Dispatcher dp = Dispatcher() dp.message.middleware(AuthCheckMiddleware())
3. 简化原业务handler
移除重复的校验逻辑,保留核心业务代码:
@menu.message(MenuFSM.menu) async def show_menu(message: Message, state: FSMContext): builder = ReplyKeyboardBuilder() builder.row(KeyboardButton(text="Меню")) await message.answer("HI", reply_markup=builder.as_markup(resize_keyboard=True, one_time_keyboard=True))
注意事项
- 若需要在用户未通过校验时发送提示,可在
raise SkipHandler()前添加消息发送逻辑 - 可根据事件类型(如
CallbackQuery)编写对应中间件,统一处理不同交互场景的认证校验 - 中间件的执行顺序可通过注册时的参数调整,确保认证校验优先于其他业务中间件执行
内容的提问来源于stack exchange,提问作者wendland0d
相关产品推荐
相关产品推荐

