Skip to content

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_FILESSL_CERT_DIR

requests 不同,httpx 包不会自动读取 环境变量 SSL_CERT_FILESSL_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 的服务),则需要创建并使用自己的证书。以下是实现方法...

  1. 使用 trustme 生成一对服务器密钥/证书文件,以及客户端证书文件。
  2. 启动本地服务器时传入服务器密钥/证书文件(具体取决于使用的 Web 服务器。例如 Uvicorn 提供了 --ssl-keyfile--ssl-certfile 选项)。
  3. 配置 httpx 使用存储在 client.pem 中的证书。
ctx = ssl.create_default_context(cafile="client.pem")
client = httpx.Client(verify=ctx)