Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

文档快速上手中,解析加密XML消息报错问题,并且已经发现原因在哪里 #630

Open
ShanChuangxin opened this issue Feb 20, 2021 · 3 comments
Labels

Comments

@ShanChuangxin
Copy link

问题描述 (Description)

文档快速上手中,解析加密XML消息报错

配置信息 (Environment/Version)

  • OS

Windows

  • Python

3.6

  • wechatpy

1.8.14?我pip list中打印的版本号

重现步骤 (Reproducing)

  1. 服务器获取微信的ComponentVerifyTicket推送
  2. 把推送按照文档快速上手中的示例代码执行
  3. 报错:
    Traceback (most recent call last):
    File "parse.py", line 36, in
    msg = parse_message(decrypted_xml)
    File "C:\Users\shan\AppData\Local\Programs\Python\Python36\lib\site-packages\wechatpy\parser.py", line 30, in parse_message
    message_type = message['MsgType'].lower()
    KeyError: 'MsgType'

然后我到报错路径下看了一下,报错中的message中没有MsgType这个字段,打印message如下:
OrderedDict([('AppId', 'wxxxxxxxxxxx'), ('CreateTime', '1613799402'), ('InfoType', 'component_verify_ticket'), ('ComponentVerifyTicket', 'ticket@@@GFBIxrYKYD9VG3tlFTOELaqaM7edWUwRbOb58mtcMFvmV0reptOv8UnBFaWvjESNHmeKVvrs_a1afk9n6zOiiA')])

我现在是采取如下方案解决了问题:
import xmltodict
from wechatpy.utils import to_text

crypto = WeChatCrypto(token, encoding_aes_key, appid)
try:
decrypted_xml = crypto.decrypt_message(
xml,
msg_signature,
timestamp,
nonce
)
except (InvalidAppIdException, InvalidSignatureException):
# 处理异常或忽略
pass

msg = xmltodict.parse(to_text(decrypted_xml))['xml']

是我哪里调用的方式出错了吗?

@LKI
Copy link
Collaborator

LKI commented Feb 20, 2021

你可以看一下是不是在处理 ComponentVerityTicket 的地方调用了 wechatpy.parser.parse_message (不能这么调用)

wechatpy.parser.parse_message 这个方法是用来处理一般的事件推送的,微信的 ComponentVerifyTicket 是在开放平台中额外配置的回调地址,得单独处理才行

@ShanChuangxin
Copy link
Author

你可以看一下是不是在处理 ComponentVerityTicket 的地方调用了 wechatpy.parser.parse_message (不能这么调用)

wechatpy.parser.parse_message 这个方法是用来处理一般的事件推送的,微信的 ComponentVerifyTicket 是在开放平台中额外配置的回调地址,得单独处理才行

我是在ConponentVerifyTicket的回调地址里把腾讯推送的xml、msg_signature、timestamp、nonce都以日志的方式保存下来,然后用这些数据尝试按照文档中快速上手中的示例调用出现的。

@LKI
Copy link
Collaborator

LKI commented Mar 3, 2021

TL;DR: 不要用 wechatpy.parser.parse_message,要用 wechatpy.component.WeChatComponent.cache_component_verify_ticket

解释:

微信推送的样例数据应该是这样子的(与普通的公众号推送不一样):

<xml>
<AppId>some_appid</AppId>
<CreateTime>1413192605</CreateTime>
<InfoType>component_verify_ticket</InfoType>
<ComponentVerifyTicket>some_verify_ticket</ComponentVerifyTicket>
</xml>

对应文档上标准写法是

from wechatpy import WeChatComponent

component = WeChatComponent('app_id', 'app_secret', 'component_token', 'encoding_aes_key')
component.cache_component_verify_ticket(self, msg, signature, timestamp, nonce)

@LKI LKI added question and removed bug labels Mar 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants