身份验证

默认情况下,requests 支持基本身份验证和 HTTP 摘要身份验证。还有一些第三方库可用于以下身份验证:

除了这些之外,requests_toolbelt.auth 还提供了额外的身份验证功能。它提供了以下身份验证类

AuthHandler

AuthHandler 是一种使用单个会话访问多个需要身份验证的网站的方法。如果您知道哪些网站需要某种身份验证以及您的凭据是什么。

以需要对 GitHub API 和 GitLab API 进行身份验证的会话为例,您将设置并使用您的 AuthHandler 如下所示

import requests
from requests_toolbelt.auth.handler import AuthHandler

def gitlab_auth(request):
    request.headers['PRIVATE-TOKEN'] = 'asecrettoken'

handler = AuthHandler({
    'https://api.github.com': ('sigmavirus24', 'apassword'),
    'https://gitlab.com': gitlab_auth,
})

session = requests.Session()
session.auth = handler
r = session.get('https://api.github.com/user')
# assert r.ok
r2 = session.get('https://gitlab.com/api/v3/projects')
# assert r2.ok

注意

必须提供身份验证的方案和域。AuthHandler 类将检查方案和主机,以确保您的数据不会意外泄露。

class requests_toolbelt.auth.handler.AuthHandler(strategies)

AuthHandler 对象采用一个将域与身份验证策略配对的字典,并使用此字典来确定在发出请求时使用哪些凭据。例如,您可以执行以下操作

from requests import HTTPDigestAuth
from requests_toolbelt.auth.handler import AuthHandler

import requests

auth = AuthHandler({
    'https://api.github.com': ('sigmavirus24', 'fakepassword'),
    'https://example.com': HTTPDigestAuth('username', 'password')
})

r = requests.get('https://api.github.com/user', auth=auth)
# => <Response [200]>
r = requests.get('https://example.com/some/path', auth=auth)
# => <Response [200]>

s = requests.Session()
s.auth = auth
r = s.get('https://api.github.com/user')
# => <Response [200]>

警告

requests.auth.HTTPDigestAuth 尚未支持线程安全。如果您在多个线程中使用 AuthHandler,则应为每个线程实例化一个新的 AuthHandler,并为每个线程实例化一个新的 HTTPDigestAuth 实例。

add_strategy(domain, strategy)

添加新的域和身份验证策略。

参数:
  • domain (str) – 您希望匹配的域。例如:'https://api.github.com'

  • strategy (str) – 您希望用于该域的身份验证策略。例如:('username', 'password')requests.HTTPDigestAuth('username', 'password')

a = AuthHandler({})
a.add_strategy('https://api.github.com', ('username', 'password'))
get_strategy_for(url)

检索指定 URL 的身份验证策略。

参数:

url (str) – 您将针对其发出请求的完整 URL。例如,'https://api.github.com/user'

返回:

可向请求添加身份验证的可调用对象。

import requests
a = AuthHandler({'example.com', ('foo', 'bar')})
strategy = a.get_strategy_for('http://example.com/example')
assert isinstance(strategy, requests.auth.HTTPBasicAuth)
remove_strategy(domain)

从策略集合中移除域和策略。

参数:

domain (str) – 您希望移除的域。例如,'https://api.github.com'

a = AuthHandler({'example.com', ('foo', 'bar')})
a.remove_strategy('example.com')
assert a.strategies == {}

GuessAuth

GuessAuth 身份验证类自动检测是否使用基本身份验证或摘要身份验证

import requests
from requests_toolbelt.auth import GuessAuth

requests.get('http://httpbin.org/basic-auth/user/passwd',
             auth=GuessAuth('user', 'passwd'))
requests.get('http://httpbin.org/digest-auth/auth/user/passwd',
             auth=GuessAuth('user', 'passwd'))

身份验证类型的检测通过服务器发送的 WWW-Authenticate 标头完成。这在基本身份验证的情况下需要一个附加请求,因为通常基本身份验证是预先发送的。如果服务器没有明确要求身份验证,则不会发送任何凭据。

class requests_toolbelt.auth.guess.GuessAuth(username, password)

通过 WWW-Authentication 标头猜测身份验证类型。

GuessProxyAuth

当对提供的代理进行身份验证时,GuessProxyAuth 处理程序将自动检测是否使用基本身份验证或摘要身份验证。

import requests
from requests_toolbelt.auth.guess import GuessProxyAuth

proxies = {
    "http": "http://PROXYSERVER:PROXYPORT",
    "https": "http://PROXYSERVER:PROXYPORT",
}
requests.get('http://httpbin.org/basic-auth/user/passwd',
             auth=GuessProxyAuth('user', 'passwd', 'proxyusr', 'proxypass'),
             proxies=proxies)
requests.get('http://httpbin.org/digest-auth/auth/user/passwd',
             auth=GuessProxyAuth('user', 'passwd', 'proxyusr', 'proxypass'),
             proxies=proxies)

身份验证类型的检测通过服务器发送的 Proxy-Authenticate 标头完成。这在基本身份验证的情况下需要一个附加请求,因为通常基本身份验证是预先发送的。如果服务器没有明确要求身份验证,则不会发送任何凭据。

class requests_toolbelt.auth.guess.GuessProxyAuth(username=None, password=None, proxy_username=None, proxy_password=None)

通过 WWW-Authentication 和 Proxy-Authentication 标头猜测身份验证类型

HTTPProxyDigestAuth

HTTPProxyDigestAuth 在客户端和代理之间使用摘要认证。

import requests
from requests_toolbelt.auth.http_proxy_digest import HTTPProxyDigestAuth


proxies = {
    "http": "http://PROXYSERVER:PROXYPORT",
    "https": "https://PROXYSERVER:PROXYPORT",
}
url = "https://toolbelt.pythonlang.cn/"
auth = HTTPProxyDigestAuth("USERNAME", "PASSWORD")
requests.get(url, proxies=proxies, auth=auth)

如果代理拒绝用户名或密码,程序会引发错误。

class requests_toolbelt.auth.http_proxy_digest.HTTPProxyDigestAuth(*args, **kwargs)

代理之间的 HTTP 摘要认证

参数:

stale_rejects (int) – 拒绝次数表示:客户端可能希望使用新的加密响应重试请求,而无需提示用户输入新的用户名和密码。即,重试 build_digest_header