SSL
在通过 HTTPS 发起请求时,HTTPX 需要验证请求主机的身份。为此,它使用由受信任证书颁发机构(CA)提供的 SSL 证书包(即 CA 证书包)。
启用和禁用验证
默认情况下,httpx 会验证 HTTPS 连接,并在 SSL 证书无效时抛出错误...
>>> httpx.get("https://expired.badssl.com/")
httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:997)
你可以完全禁用 SSL 验证以允许不安全的请求...
>>> httpx.get("https://expired.badssl.com/", verify=False)
<Response [200 OK]>
配置客户端实例
如果使用 Client()
实例,应在初始化客户端时传入 verify=<...>
配置。
默认使用 certifi CA 证书包 进行 SSL 验证。
对于更复杂的配置,可以传入 SSL 上下文 实例...
import certifi
import httpx
import ssl
# 此 SSL 上下文等效于默认的 `verify=True`
ctx = ssl.create_default_context(cafile=certifi.where())
client = httpx.Client(verify=ctx)
使用 truststore 包 支持系统证书存储...
import ssl
import truststore
import httpx
# 使用系统证书存储
ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client = httpx.Client(verify=ctx)
通过 标准 SSL 上下文 API 加载替代证书验证存储...
import httpx
import ssl
# 使用显式配置的证书存储
ctx = ssl.create_default_context(cafile="path/to/certs.pem") # 可使用 cafile 或 capath
client = httpx.Client(verify=ctx)
客户端证书
客户端证书允许远程服务器验证客户端身份。这类证书通常用于私有组织内部,用于向远程服务器验证请求。
您可以使用 .load_cert_chain()
API 来指定客户端证书...
ctx = ssl.create_default_context()
ctx.load_cert_chain(certfile="path/to/client.pem") # 可选地也可以指定 keyfile 或 password。
client = httpx.Client(verify=ctx)
使用 SSL_CERT_FILE
和 SSL_CERT_DIR
与 requests
不同,httpx
包不会自动读取 环境变量 SSL_CERT_FILE
或 SSL_CERT_DIR
。如需使用这些变量,需要显式启用。
例如...
# 如果配置了则使用 `SSL_CERT_FILE` 或 `SSL_CERT_DIR`。
# 否则默认使用 certifi。
ctx = ssl.create_default_context(
cafile=os.environ.get("SSL_CERT_FILE", certifi.where()),
capath=os.environ.get("SSL_CERT_DIR"),
)
client = httpx.Client(verify=ctx)
向本地服务器发起 HTTPS 请求
当向本地服务器(例如运行在 localhost
上的开发服务器)发起请求时,通常会使用未加密的 HTTP 连接。
如果你确实需要向本地服务器建立 HTTPS 连接(例如测试仅支持 HTTPS 的服务),则需要创建并使用自己的证书。以下是实现方法...
- 使用 trustme 生成一对服务器密钥/证书文件,以及客户端证书文件。
- 启动本地服务器时传入服务器密钥/证书文件(具体取决于使用的 Web 服务器。例如 Uvicorn 提供了
--ssl-keyfile
和--ssl-certfile
选项)。 - 配置
httpx
使用存储在client.pem
中的证书。
ctx = ssl.create_default_context(cafile="client.pem")
client = httpx.Client(verify=ctx)