ImportAuthorizationRequest无报错但客户端未授权,get_me返回None的问题排查
我之前也踩过Telethon里导入授权后会话无效的坑,结合你的代码和描述,咱们一步步来排查解决:
首先,最核心的问题是DC ID逻辑完全混乱,你代码里的DC处理从头到尾都不对:
- 你先获取了
config.dc_options[0].id作为要使用的DC,但导出授权时硬写了dc_id=2; - 导入后又随便调用
set_dc用了target_dc_id,还乱传了会话里的旧参数。
Telethon的授权是和DC绑定的——ExportAuthorizationRequest导出的是对应DC的授权凭证,导入时客户端必须处于同一个DC,否则就算导入不报错,这个授权在当前DC下也是无效的,自然get_me拿不到任何信息。
第一步:统一DC ID,修正导出导入逻辑
把导出授权的DC ID改成和你要使用的目标DC一致,别硬写死2:
# 之前你已经获取了正确的DC ID dc_id = config.dc_options[0].id # 导出对应DC的授权,而不是硬写2 auth_data = await original_client(functions.auth.ExportAuthorizationRequest(dc_id=dc_id))
第二步:导入前先正确设置客户端的DC
你之前是先connect再导入,还在导入后乱改DC,这会导致客户端连接的服务器和授权凭证对应的DC不匹配。正确的顺序是:初始化客户端后,先设置好DC信息,再调用connect:
# 先从config里拿到目标DC的完整信息 target_dc = config.dc_options[0] # 初始化新客户端后,直接设置DC new_client = TelegramClient( f'cloned\\{me.phone}', api_id, api_hash, proxy=None, device_model='Edge 117.0.2045.47', system_version='Windows', app_version='10.9.56 A', system_lang_code='en-us', lang_code='en' ) # 用目标DC的真实地址和端口设置会话 new_client.session.set_dc( dc_id=dc_id, server_address=target_dc.ip_address, port=target_dc.port ) # 现在再连接 await new_client.connect()
第三步:导入授权后显式保存会话状态
导入授权返回Authorization对象只是说明导入操作本身成功,但Telethon的会话状态不会自动写入文件,你需要显式保存:
info = await new_client(functions.auth.ImportAuthorizationRequest(id=auth_data.id, bytes=auth_data.bytes)) logger.info("Authorization imported successfully") # 显式保存会话 await new_client.session.save() # 可以断开再重新连接,让客户端重新加载完整的会话状态 await new_client.disconnect() await new_client.connect()
第四步:验证会话状态
做完上面的步骤后,再调用get_me,应该就能返回User对象了。另外你可以直接打印会话的user_id,提前验证:
print(new_client.session.user_id) # 输出你的用户ID,说明会话已授权 me = await new_client.get_me() print(me) # 现在应该返回User(...)对象了
关于设备列表和会话文件的补充说明
你说授权不在设备列表里,这是正常的——用Export/ImportAuthorizationRequest导入的是授权凭证,不是通过登录流程创建的设备会话,所以不会显示在Telegram的“已登录设备”列表里,但会话文件里应该会有auth_key和user_id的信息了。
最后再提一句:你之前手动调用set_dc的参数完全错了,不能传new_client.session里的旧值,必须用目标DC的真实ip和端口,也就是从config.dc_options里拿的那些。
内容来源于stack exchange

