我正在尝试使用 asyncio 和 aiohttp 实现异步客户端,我有 API 凭据和 mTLS 证书来连接到某些服务的端点。但是当我打电话时它会挂起(直到超时)并给出<ClientResponse(https://<some endpoint>:8443/login) [504 Gateway Time-out]>
实现相同但不异步(带有请求)工作得很好(在请求中提供带有 certs= 的证书)。
AFAIU,问题出在 ssl 上下文区域的某个地方……但我找不到……
class Test:
def __init__(self, url: str):
self.url = url
self.api_creds = {"api_key": os.getenv("API_KEY"), "api_secret": os.getenv("API_SECRET")}
self.headers = {"Content-Type": "application/json;charset=utf-8", "Content-Length": "20000"}
async def _post(self, path, payload):
url = self.url + path
sslcontext = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
sslcontext.load_cert_chain(certfile='Path to mtls.crt', keyfile='Path .key')
async with aiohttp.ClientSession(headers=headers) as session:
try:
response = await session.post(url, data=payload, ssl=sslcontext)
except (aiohttp.ClientConnectorSSLError, aiohttp.ClientConnectorCertificateError) as e:
logger.error(str(e))
return response
async def login(self):
response = await self._post('/login', self.api_creds)
print(response)
async def main():
t = Test("https://EP url")
await t.login()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
输出:DEBUG asyncio : Using selector: KqueueSelector
DEBUG asyncio : Get address info <EP>:8443, type=<SocketKind.SOCK_STREAM: 1>, flags=<AddressInfo.AI_ADDRCONFIG: 1024>
DEBUG asyncio : Getting address info <EP>:8443, type=<SocketKind.SOCK_STREAM: 1>, flags=<AddressInfo.AI_ADDRCONFIG: 1024> took 47.029ms: [(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('<IP>', 8443)), (<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('<IP>', 8443)), (<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('<IP>', 8443))]
DEBUG asyncio : <asyncio.sslproto.SSLProtocol object at 0x102e2ab20> starts SSL handshake
DEBUG asyncio : <asyncio.sslproto.SSLProtocol object at 0x102e2ab20>: SSL handshake took 188.5 ms
DEBUG asyncio : <asyncio.TransportSocket fd=9, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6, laddr=('192.168.86.20', 53514), raddr=('<IP>', 8443)> connected to <IP>:8443: (<asyncio.sslproto._SSLProtocolTransport object at 0x102f53be0>, <aiohttp.client_proto.ResponseHandler object at 0x102eebb80>)
<ClientResponse(https://EP:8443/login) [504 Gateway Time-out]>
最佳答案
您可以使用 ssl 默认上下文:
sslcontext = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
sslcontext.load_cert_chain(certfile=cert_path, keyfile=key_path)
tcpconn = aiohttp.TCPConnector(ssl_context=sslcontext)
async with aiohttp.ClientSession(
connector=tcpconn,
headers={"Accept": "application/json"},
) as client:
client.post(url, data=payload)
关于python - 带有 ssl 客户端证书的 aiohttp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69816038/