如何在aiogram中实现验证密码后才可使用/number命令?
问题出在哪?
你这代码有俩致命问题:
- 处理器不能动态加:你把
/number的处理函数塞在state_pass里面了,aiogram的命令处理器是程序启动时就注册好的,运行时临时加的根本不生效,所以输/number没反应。 - 没记用户是否验证过:验证完密码就完了,没存下这个用户已经通过验证的状态,就算处理器能生效,谁都能调用
/number,根本没起到限制作用。
改好的代码来了
用全局集合存已验证的用户ID,再加个过滤器管权限,这样只有验证过的人才能用/number:
from aiogram import Bot, Dispatcher, executor, types from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.dispatcher import FSMContext from aiogram.dispatcher.filters.state import StatesGroup, State from aiogram.dispatcher.filters import Filter TOKEN = "mytoken" bot = Bot(token=TOKEN) storage = MemoryStorage() dp = Dispatcher(bot, storage=storage) # 存已经通过密码验证的用户ID,重启机器人会清空,要持久化就换数据库 authorized_users = set() class FSMStates(StatesGroup): 等待密码输入 = State() 等待客户号输入 = State() # 自定义过滤器:检查用户是不是已经验证过 class 已授权(Filter): async def check(self, message: types.Message): return message.from_user.id in authorized_users @dp.message_handler(commands=["start"]) async def 处理启动命令(message: types.Message): await message.reply("要使用功能先输/password验证身份") @dp.message_handler(commands=["password"]) async def 请求输入密码(message: types.Message): await message.answer("请输入密码") await FSMStates.等待密码输入.set() @dp.message_handler(state=FSMStates.等待密码输入) async def 验证密码正确性(message: types.Message, state: FSMContext): if message.text == "hksdf": # 密码正确,将用户ID加入授权列表 authorized_users.add(message.from_user.id) await message.answer("验证成功!现在可以使用/number命令输入客户号") await state.finish() else: await message.answer("密码错误,请重新输入") # 仅已授权用户能触发该/number处理器 @dp.message_handler(已授权(), commands=["number"]) async def 请求输入客户号(message: types.Message): await message.answer("请输入客户号") await FSMStates.等待客户号输入.set() # 未授权用户调用/number时的提示 @dp.message_handler(commands=["number"]) async def 未授权提示(message: types.Message): await message.reply("请先输入/password验证身份") if __name__ == '__main__': executor.start_polling(dp, skip_updates=True)
关键改动说明
- 全局集合
authorized_users:临时存储验证通过的用户ID,重启机器人后会清空,若需持久化可替换为Redis、SQLite等存储方式。 - 自定义过滤器
已授权:专门用于控制/number命令的访问权限,只有验证过的用户才能触发对应的处理逻辑。 - 拆分FSM状态:将原单一状态拆分为「等待密码输入」和「等待客户号输入」,避免状态混淆,逻辑更清晰。
- 处理器移至全局作用域:把
/number的处理函数放在全局区域,确保程序启动时就完成注册,保证命令能正常触发。
内容的提问来源于stack exchange,提问作者Вася ссирнов
相关产品推荐
相关产品推荐

