import aiohttp from app.core.config import settings import requests from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization import json import base64 import time import random import string from cryptography.x509 import load_pem_x509_certificate from cryptography.hazmat.primitives.ciphers.aead import AESGCM def generate_random_string(length=32): """生成指定长度的随机字符串""" return ''.join(random.choices(string.ascii_letters + string.digits, k=length)) class WeChatClient: """微信客户端""" def __init__(self): self.appid = settings.WECHAT_APPID self.secret = settings.WECHAT_SECRET async def get_access_token(self): """获取接口调用凭证""" if self.access_token: return self.access_token async with aiohttp.ClientSession() as session: url = f"https://api.weixin.qq.com/cgi-bin/token" params = { "grant_type": "client_credential", "appid": self.appid, "secret": self.secret } async with session.get(url, params=params) as response: result = await response.json() if "access_token" in result: self.access_token = result["access_token"] return self.access_token raise Exception(result.get("errmsg", "获取access_token失败")) async def get_phone_number(self, code: str): """获取用户手机号""" access_token = await self.get_access_token() async with aiohttp.ClientSession() as session: url = f"https://api.weixin.qq.com/wxa/business/getuserphonenumber" params = {"access_token": access_token} data = {"code": code} async with session.post(url, params=params, json=data) as response: result = await response.json() if result.get("errcode") == 0: return result.get("phone_info") raise Exception(result.get("errmsg", "获取手机号失败")) async def code2session(self, code: str) -> dict: """通过 code 获取用户 openid Args: code: 登录凭证 Returns: dict: 包含 openid 等信息 """ async with aiohttp.ClientSession() as session: url = "https://api.weixin.qq.com/sns/jscode2session" params = { "appid": self.appid, "secret": self.secret, "js_code": code, "grant_type": "authorization_code" } async with session.get(url, params=params) as response: result = await response.json() if "openid" in result: return result raise Exception(result.get("errmsg", "获取openid失败"))