使用 Python 的 HTTPBasicAuthHandler 进行 Bitbucket API 身份验证

发布于 2024-08-29 09:55:10 字数 2238 浏览 4 评论 0 原文

我正在尝试使用 bitbucket 的 API 获取私有存储库上的问题列表。

I have confirmed that HTTP Basic authentication works with hurl, but I am unable to authenticate in Python.改编此 教程 中的代码,我编写了以下脚本。

import cookielib
import urllib2

class API():
    api_url = 'http://api.bitbucket.org/1.0/'

    def __init__(self, username, password):
        self._opener = self._create_opener(username, password)

    def _create_opener(self, username, password):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
        password_manager.add_password(None, self.api_url, username, password)
        auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
        opener = urllib2.build_opener(cookie_handler, auth_handler)
        return opener

    def get_issues(self, username, repository):
        query_url = self.api_url + 'repositories/%s/%s/issues/' % (username, repository)
        try:
            handler = self._opener.open(query_url)
        except urllib2.HTTPError, e:
            print e.headers
            raise e
        return handler.read()

api = API(username='my_username', password='XXXXXXXX')

api.get_issues('my_username', 'my_repository') 结果:

>>> 
Server: nginx/0.7.62
Date: Mon, 19 Apr 2010 16:15:06 GMT
Content-Type: text/plain
Connection: close
Vary: Authorization,Cookie
Content-Length: 9

Traceback (most recent call last):
  File "C:/USERS/personal/bitbucket-burndown/bitbucket-api.py", line 29, in <module>
    print api.get_issues('my_username', 'my_repository')
  File "C:/USERS/personal/bitbucket-burndown/bitbucket-api.py", line 25, in get_issues
    raise e
HTTPError: HTTP Error 401: UNAUTHORIZED

api.get_issues('jespern', 'bitbucket') 工作起来就像一个魅力。

我的代码有什么问题吗?

I'm trying to get the list of issues on a private repository using bitbucket's API.

I have confirmed that HTTP Basic authentication works with hurl, but I am unable to authenticate in Python. Adapting the code from this tutorial, I have written the following script.

import cookielib
import urllib2

class API():
    api_url = 'http://api.bitbucket.org/1.0/'

    def __init__(self, username, password):
        self._opener = self._create_opener(username, password)

    def _create_opener(self, username, password):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
        password_manager.add_password(None, self.api_url, username, password)
        auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
        opener = urllib2.build_opener(cookie_handler, auth_handler)
        return opener

    def get_issues(self, username, repository):
        query_url = self.api_url + 'repositories/%s/%s/issues/' % (username, repository)
        try:
            handler = self._opener.open(query_url)
        except urllib2.HTTPError, e:
            print e.headers
            raise e
        return handler.read()

api = API(username='my_username', password='XXXXXXXX')

api.get_issues('my_username', 'my_repository') results in:

>>> 
Server: nginx/0.7.62
Date: Mon, 19 Apr 2010 16:15:06 GMT
Content-Type: text/plain
Connection: close
Vary: Authorization,Cookie
Content-Length: 9

Traceback (most recent call last):
  File "C:/USERS/personal/bitbucket-burndown/bitbucket-api.py", line 29, in <module>
    print api.get_issues('my_username', 'my_repository')
  File "C:/USERS/personal/bitbucket-burndown/bitbucket-api.py", line 25, in get_issues
    raise e
HTTPError: HTTP Error 401: UNAUTHORIZED

api.get_issues('jespern', 'bitbucket') works like a charm.

What's wrong with my code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

淡笑忘祈一世凡恋 2024-09-05 09:55:10

HTTPBasicAuthHandler 似乎存在问题。这有效:

class API():
    api_url = 'http://api.bitbucket.org/1.0/'

    def __init__(self, username, password, proxy=None):
        encodedstring = base64.encodestring("%s:%s" % (username, password))[:-1]
        self._auth = "Basic %s" % encodedstring
        self._opener = self._create_opener(proxy)

    def _create_opener(self, proxy=None):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        if proxy:
            proxy_handler = urllib2.ProxyHandler(proxy)
            opener = urllib2.build_opener(cookie_handler, proxy_handler)
        else:
            opener = urllib2.build_opener(cookie_handler)
        return opener

    def get_issues(self, username, repository):
        query_url = self.api_url + 'repositories/%s/%s/issues/' % (username, repository)
        try:
            req = urllib2.Request(query_url, None, {"Authorization": self._auth })
            handler = self._opener.open(req)
        except urllib2.HTTPError, e:
            print e.headers
            raise e
        return json.load(handler)

It looks like there is an issue with HTTPBasicAuthHandler. This works:

class API():
    api_url = 'http://api.bitbucket.org/1.0/'

    def __init__(self, username, password, proxy=None):
        encodedstring = base64.encodestring("%s:%s" % (username, password))[:-1]
        self._auth = "Basic %s" % encodedstring
        self._opener = self._create_opener(proxy)

    def _create_opener(self, proxy=None):
        cj = cookielib.LWPCookieJar()
        cookie_handler = urllib2.HTTPCookieProcessor(cj)
        if proxy:
            proxy_handler = urllib2.ProxyHandler(proxy)
            opener = urllib2.build_opener(cookie_handler, proxy_handler)
        else:
            opener = urllib2.build_opener(cookie_handler)
        return opener

    def get_issues(self, username, repository):
        query_url = self.api_url + 'repositories/%s/%s/issues/' % (username, repository)
        try:
            req = urllib2.Request(query_url, None, {"Authorization": self._auth })
            handler = self._opener.open(req)
        except urllib2.HTTPError, e:
            print e.headers
            raise e
        return json.load(handler)
嘿哥们儿 2024-09-05 09:55:10

我认为 Python 的 HTTPBasicAuthHandler 中没有错误。基本身份验证通常遵循以下过程:

  • 客户端在没有凭据的情况下发出请求;
  • 服务器响应401错误;
  • 客户端重新发送带有凭据的请求;
  • 服务器响应内容。

对于 BitBucket,会发生这种情况:

  • 客户端在没有凭据的情况下发出请求;
  • BitBucket 以公共存储库列表进行响应。

BitBucket 从不发出 401,因此 Python 从不发送凭据。

查看此示例,以在不使用 cookie 的情况下使用 BitBucket 进行身份验证:

I don't think there's an error in Python's HTTPBasicAuthHandler. Basic authentication usually follows this process:

  • Client makes request without credentials;
  • Server responds with 401 error;
  • Client resends request with credentials;
  • Server responds with content.

In the case of BitBucket, this happens:

  • Client makes request without credentials;
  • BitBucket responds with list of public repositories.

BitBucket never issues the 401, so Python never sends the credentials.

Have a look at this example for authenticating with BitBucket without using cookies:

尹雨沫 2024-09-05 09:55:10

看一下python-bitbucket,它是 Bitbucket API 的 python 包装器。 原始库仅包含读取访问权限,但ericof 包括身份验证和一些写入访问权限,我已将其引入并在此基础上构建:https://bitbucket.org/bkmontgomery/python-bitbucket

您可以从私人存储库中检索问题,如下所示:

import bitbucket

bb = bitbucket.BitBucket(username='your-username', password='secret')
repo = bb.repository('your-username', 'your-private-repo')
issues = repo.issues()

Take a look at python-bitbucket, which is a python wrapper for Bitbucket's API. The original library only includes read access, but ericof included authentication and some write access, which I've pulled in and built upon here: https://bitbucket.org/bkmontgomery/python-bitbucket

You could retrieve Issues from a private repo as follows:

import bitbucket

bb = bitbucket.BitBucket(username='your-username', password='secret')
repo = bb.repository('your-username', 'your-private-repo')
issues = repo.issues()
不必你懂 2024-09-05 09:55:10

您可以尝试对 HTTPPasswordMgr 进行子类化并重写 find_user_password() 方法,以查看代码在何处放弃查找密码。我的猜测是 add_password() 并没有完全按照您的预期进行。

You could try sub-classing HTTPPasswordMgr and overriding the find_user_password() method to see where your code is giving up on finding the password. My guess is that add_password() isn't doing exactly what you'd expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文