Skip to content

Requests - 认证

requests 库简化了 HTTP 中使用的各种认证方案。本章涵盖了一些常见的类型。

  • 理解 HTTP 认证
  • 基本认证 (Basic Authentication)
  • 摘要认证 (Digest Authentication)
  • OAuth 2.0 认证(使用 requests-oauthlib)

HTTP 认证涉及客户端向服务器发送凭据(如用户名和密码)以访问受保护的资源。服务器通常会通过 401 Unauthorized 响应来要求客户端提供这些凭据。然后客户端会重新发送请求,并在 Authorization 请求头中包含凭据。

requests 为 Basic 和 Digest 等常见认证方法提供了内置支持,并允许自定义认证处理程序。

HTTP 基本认证 (Basic Authentication) 是一种简单的方案,其中用户名和密码组合后进行 Base64 编码,然后发送到 Authorization 请求头中。虽然简单,但在未加密的 HTTP 连接上使用不安全。

requests 使用 auth 参数提供了一个快捷方式,该参数可以接受一个元组 (username, password) 或一个 HTTPBasicAuth 实例。

import requests
from requests.auth import HTTPBasicAuth
# httpbin.org 用于基本认证的端点是 /basic-auth/user/passwd
target_url = 'https://httpbin.org/basic-auth/myuser/mypassword'
username = 'myuser'
password = 'mypassword'
try:
# 您可以直接将元组传递给 auth 参数
# response = requests.get(target_url, auth=(username, password))
# 或者显式使用 HTTPBasicAuth 类
response = requests.get(target_url, auth=HTTPBasicAuth(username, password))
response.raise_for_status() # 检查 HTTP 错误
print("Authentication successful!")
print(response.json())
except requests.exceptions.HTTPError as e:
print(f"Authentication failed or other HTTP error: {e.response.status_code} {e.response.reason}")
except requests.exceptions.RequestException as e:
print(f"A request error occurred: {e}")
Authentication successful!
{'authenticated': True, 'user': 'myuser'}

如果您提供了不正确的凭据或尝试在未认证的情况下访问,httpbin.org 将返回 401 Unauthorized 状态。

摘要认证 (Digest Authentication) 比基本认证更安全,因为它不以明文形式发送密码。相反,它使用一种涉及散列的挑战-响应机制。

requests 通过 HTTPDigestAuth 支持此功能。

import requests
from requests.auth import HTTPDigestAuth
# httpbin.org 用于摘要认证的端点是 /digest-auth/qop/user/passwd
# qop 可以是 'auth' 或 'auth-int'
target_url = 'https://httpbin.org/digest-auth/auth/myuser/mypassword'
username = 'myuser'
password = 'mypassword'
try:
response = requests.get(target_url, auth=HTTPDigestAuth(username, password))
response.raise_for_status()
print("Digest Authentication successful!")
print(response.json())
except requests.exceptions.HTTPError as e:
print(f"Authentication failed or other HTTP error: {e.response.status_code} {e.response.reason}")
except requests.exceptions.RequestException as e:
print(f"A request error occurred: {e}")
Digest Authentication successful!
{'authenticated': True, 'user': 'myuser'}

使用 requests-oauthlib 进行 OAuth 2.0 认证

Section titled “使用 requests-oauthlib 进行 OAuth 2.0 认证”

OAuth 2.0 是一种开放标准的访问授权协议,常用于第三方应用程序访问网络服务上的用户数据,而无需暴露用户凭据。它比基本认证或摘要认证更复杂。

requests-oauthlib 库将 OAuth 功能与 requests 集成。首先,安装它:

pip install requests-oauthlib

OAuth 2.0 流程通常涉及几个步骤:将用户重定向到授权服务器,用户授权,授权服务器重定向回应用程序并带有授权码,最后应用程序使用此授权码交换访问令牌 (access token)。然后使用访问令牌进行认证后的 API 请求。

在此示例中,我们将重点介绍第一步:生成授权 URL。您需要一个 client_id(客户端 ID),通常还需要一个 client_secret(客户端密钥),通过在 OAuth 提供方(例如,Google、GitHub、Twitter)注册您的应用程序获得。

from requests_oauthlib import OAuth2Session
# 替换为您从 OAuth 提供方获得的实际客户端 ID
client_id = 'YOUR_CLIENT_ID_HERE'
# 重定向 URI 必须与您的 OAuth 应用程序中注册的一致
redirect_uri = 'https://your-app.com/callback'
# OAuth 服务提供的授权端点 URL
# 例如,Google 的是 'https://accounts.google.com/o/oauth2/v2/auth'
authorization_base_url = 'https://some-oauth-provider.com/oauth/authorize'
# Scopes (作用域) 定义您的应用程序请求的权限
scope = ['read', 'write']
# 创建一个 OAuth2Session 实例
oauth_session = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope)
# 生成授权 URL 和状态 (state)
# 'state' 参数用于防止 CSRF 攻击,您的应用程序应该存储它
authorization_url, state = oauth_session.authorization_url(authorization_base_url)
print('Please go to the following URL and authorize the application:')
print(authorization_url)
print(f'State parameter generated: {state}')
# 在实际应用中:
# 1. 将用户重定向到 authorization_url。
# 2. 用户授权。
# 3. 用户被重定向回您的 redirect_uri,并带有 'code' 和 'state' 参数。
# 4. 验证 'state' 与您存储的一致。
# 5. 使用以下方式获取令牌:
# token = oauth_session.fetch_token('TOKEN_URL', client_secret='YOUR_CLIENT_SECRET', code=CODE_FROM_REDIRECT)
# 6. 使用带有令牌的 oauth_session 发出认证后的请求:
# profile_response = oauth_session.get('https://api.some-oauth-provider.com/profile')

此代码片段仅生成 URL。一个完整的 OAuth 2.0 实现涉及处理重定向、用授权码交换令牌以及管理令牌刷新。requests-oauthlib 极大地简化了这些任务。

预期输出(URL 将根据参数而有所不同)

Section titled “预期输出(URL 将根据参数而有所不同)”
Please go to the following URL and authorize the application:
https://some-oauth-provider.com/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID_HERE&redirect_uri=https%3A%2F%2Fyour-app.com%2Fcallback&scope=read+write&state=GeneratedRandomStateValue
State parameter generated: GeneratedRandomStateValue

有关更全面的示例和不同 OAuth 2.0 授权类型,请查阅requests-oauthlib 文档以及您正在集成的 OAuth 提供方的特定文档。