我可以使用 httplib2 进行抢占式认证吗?

5 投票
3 回答
3964 浏览
提问于 2025-04-16 23:41

我需要对一个HTTP服务器进行主动的基本认证,也就是说,我想要立刻进行认证,而不是等到收到401错误响应后再认证。请问这可以用httplib2来实现吗?

补充:

我通过在请求中添加一个授权头来解决这个问题,正如被接受的回答中所建议的那样:

 headers["Authorization"] = "Basic {0}".format(
        base64.b64encode("{0}:{1}".format(username, password)))

3 个回答

1

我知道这个问题有点老了,但我想分享一个解决方案,适合使用Python 3和httplib2的朋友,因为我在其他地方找不到这个信息。我是在用API Token对每个Jenkins用户进行身份验证。如果你不关心Jenkins,只需用实际用户的密码替换API Token就可以了。

b64encode需要的是一串ASCII字符的二进制字符串。在Python 3中,如果直接传入普通字符串,会出现类型错误。为了解决这个问题,头部中的"user:api_token"部分必须用'ascii'或'utf-8'进行编码,然后传给b64encode,最后得到的字节字符串需要解码成普通字符串,才能放入头部。以下代码实现了我需要的功能:

import httplib2, base64

cred = base64.b64encode("{0}:{1}".format(
    <user>, <api_token>).encode('utf-8')).decode()
headers = {'Authorization': "Basic %s" % cred}
h = httplib2.Http('.cache')
response, content = h.request("http://my.jenkins.server/job/my_job/enable",
    "GET", headers=headers)
4

这段话的意思是,内置的 httplib 也可以用来实现这个功能(如果你想减少使用第三方库或模块的话)。我正在用它通过Jenkins服务器的API令牌来进行身份验证,这个令牌是Jenkins为每个用户生成的。

>>> import base64, httplib
>>> headers = {}
>>> headers["Authorization"] = "Basic {0}".format(
        base64.b64encode("{0}:{1}".format('<username>', '<jenkins_API_token>')))

>>> ## Enable the job
>>> conn = httplib.HTTPConnection('jenkins.myserver.net')
>>> conn.request('POST', '/job/Foo-trunk/enable', None, headers)
>>> resp = conn.getresponse()
>>> resp.status
302

>>> ## Disable the job
>>> conn = httplib.HTTPConnection('jenkins.myserver.net')
>>> conn.request('POST', '/job/Foo-trunk/disable', None, headers)
>>> resp = conn.getresponse()
>>> resp.status
302
4

在你第一次发送请求的时候,记得加上一个格式正确的“授权”头信息。

撰写回答