这可能是一个愚蠢的问题,但我找不到如何创建AuthHandler
的方法,它会在FIRST请求中添加Authorization
标头。我在urllib2.py中唯一看到的是各种http_error处理程序,它将Authorization
标头添加到处理错误的 ADDITIONAL 请求中。
但是,在查看http://www.ietf.org/rfc/rfc2617.txt第2节时,我看到了这一点:
客户端可以抢先发送相应的授权标头,其中包含该空间中的资源请求,而不会从服务器收到其他质询。
真的有很多服务器(例如,api.github.com)希望授权标头与初始请求一起发送,实际上他们broke因此而不是401而是发送404状态代码。
任何人都知道如何将*AuthHandler
子类化,以便在初始请求中添加标题?
python-requests
不是答案。请不要浪费我的时间来暗示它。答案必须只在stdlib的上下文中。
答案 0 :(得分:1)
好的,所以最后它是http_request
方法。因此,例如,这是向GitHub添加新错误的脚本:
from base64 import standard_b64encode
import http.client
from urllib.request import (HTTPBasicAuthHandler, Request, HTTPSHandler,
build_opener, HTTPPasswordMgrWithDefaultRealm)
import json
import os
from configparser import ConfigParser
http.client.HTTPConnection.debuglevel = 1
class HTTPBasicPriorAuthHandler(HTTPBasicAuthHandler):
handler_order = 400
def http_request(self, req):
if not req.has_header('Authorization'):
user, passwd = self.passwd.find_user_password(None,
req.get_host())
credentials = '{0}:{1}'.format(user, passwd).encode()
auth_str = standard_b64encode(credentials).decode()
req.add_unredirected_header('Authorization',
'Basic {}'.format(auth_str.strip()))
return req
https_request = http_request
cp = ConfigParser()
cp.read(os.path.expanduser('~/.githubrc'))
# That configuration file should look something like
# [github]
# user=mylogin
# password=myveryverysecretpassword
gh_user = cp.get('github', 'user')
gh_passw = cp.get('github', 'password')
repo = 'reponame'
pwd_manager = HTTPPasswordMgrWithDefaultRealm()
pwd_manager.add_password(None, 'https://api.github.com', gh_user, gh_passw)
auth_prior_handler = HTTPBasicPriorAuthHandler(pwd_manager)
verbose_handler = HTTPSHandler(debuglevel=2)
opener = build_opener(verbose_handler, auth_prior_handler)
# Be careful that there is no slash in the end of the URL
gh_url = "https://api.github.com/repos/{0}/{1}/issues".format(gh_user, repo)
create_data = {
'title': 'Testing bug summary',
'body': '''This is a testing bug. I am writing here this stuff,
just to have some text for body.''',
'labels': ['somelabel']
}
gh_req = Request(gh_url, json.dumps(create_data).encode('utf8'))
handler = opener.open(gh_req)
print(handler.getcode())
print(handler)
实际上,现在我相信这个问题的答案是使用我的urllib2_prior_auth包。