Files
sixGuoDjango/wechat_项目工具包/企业微信工具包/设置接收事件服务器通讯录.py
T
2026-08-02 14:07:04 +08:00

81 lines
3.8 KiB
Python

import base64
import hashlib
import jmespath
import xmltodict
from Crypto.Cipher import AES
from django.core.handlers.wsgi import WSGIRequest
from rest_framework.request import Request
class wecom设置接收事件服务器通讯录:
"""https://work.weixin.qq.com/wework_admin/frame#apps/contactsApi"""
# 跟认证目录下的功能是一样的(这里是留一个备份)
token = "bVWt1PEUCG" # url验证的token(当前的值为江苏六果科技有限公司)
EncodingAESKey = "LS6VsiJA6Vpb3nJlt34vMZFAbuKDJkFuH2KxuEXYuUR" # 配置的解密(当前的值为江苏六果科技有限公司)
corp_id = "wwbe6369dc26a9d83a" # 企业微信🆔(当前的值为 江苏六果科技有限公司)
corpsecret = "SIRyum7vQh-Bt36AxnqKMX0HIiE-zkYbjYgSat7reZw" # 企业微信 secret(当前的值为 江苏六果科技有限公司)
# phone_secret = "WNxZZdcU3FRS5msq_kHZaaZOBauBEjJZdQV3VrAxu0c" # 通讯录 secret
@classmethod
def post解密推送消息体(cls, msg_content: bytes):
""""""
# 从XML中找到Encrypt标签的内容,即加密数据
xmldict = xmltodict.parse(msg_content.decode())
Encrypt = jmespath.search(data=xmldict, expression="xml.Encrypt", )
# 将EncodingAESKey进行Base64解码,并补足填充字符'='
AESKey = base64.b64decode(cls.EncodingAESKey + '=')
# 创建一个AES加密器对象,使用CBC模式和指定的初始化向量(IV)
cipher = AES.new(key=AESKey, mode=AES.MODE_CBC, IV=AESKey[:16])
# 对加密数据进行Base64解码
aes_msg = base64.b64decode(Encrypt)
# 使用解密器对象解密数据
de_text = cipher.decrypt(plaintext=aes_msg)
print(de_text)
# 去除解密数据地前16个字节的随机字符串
content = de_text[16:]
# 解析前4个字节以获取XML内容的实际长度,并将其从网络字节序转换为主机字节序
# xml_len = socket.ntohl(struct.unpack("I", content[:4])[0])
xml_len = int.from_bytes(content[:4], byteorder='big')
# 根据解析出的长度提取实际的XML内容
xml_content = content[4: xml_len + 4]
# 打印XML内容
# 将XML内容解析为字典格式
as_dict = xmltodict.parse(xml_input=xml_content)
# 打印解析后的字典
return as_dict
@classmethod
def get请求算法(cls, echostr):
""""""
AESKey = base64.b64decode(cls.EncodingAESKey + '=')
aes_msg = base64.b64decode(echostr)
aes = AES.new(key=AESKey, mode=AES.MODE_CBC, iv=aes_msg[:16])
de_text = aes.decrypt(plaintext=aes_msg)
content = de_text[16:] # 去掉前16随机字节
# 取出4字节的msg_len
xml_len = int.from_bytes(content[:4], byteorder='big')
xml_content = content[4: xml_len + 4]
return xml_content
@classmethod
def get解密验证消息(cls, request: WSGIRequest | Request, ):
"""接受微信发过来的get请求,拿到参数后解决,并且回复值,结果为验证成功"""
GET_OBJ = request.query_params
signature = jmespath.search(data=GET_OBJ, expression="msg_signature", )
timestamp = jmespath.search(data=GET_OBJ, expression="timestamp", )
nonce = jmespath.search(data=GET_OBJ, expression="nonce", )
echostr = jmespath.search(data=GET_OBJ, expression="echostr", )
# TODO:sorted([token, timestamp, nonce])这是就是对三个参数进行字典排序
hashstr = ''.join(sorted([cls.token, timestamp, nonce, echostr, ])) # 这是就是对三个参数进行字典排序
sig = hashlib.new(name="sha1", data=hashstr.encode()).hexdigest()
if sig == signature:
ret = cls.get请求算法(echostr)
s = ret.decode().strip()
return s
else:
raise Exception("没有验yghd成功")