문제

I've been asked to deal with an external REST API (Zendesk's, in fact) whose credentials need to be formatted as {email}/token:{security_token} -- a single value rather than the usual username/password pair. I'm trying to use the Python requests module for this task, since it's Pythonic and doesn't hurt my brain too badly, but I'm not sure how to format the authentication credentials. The Zendesk documentation only gives access examples using curl, which I'm unfamiliar with.

Here's how I currently have requests.auth.AuthBase subclassed:

class ZDTokenAuth(requests.auth.AuthBase):
    def __init__(self,username,token):
        self.username = username
        self.token = token

    def __call__(self,r):
        auth_string = self.username + "/token:" + self.token
        auth_string = auth_string.encode('utf-8')
        r.headers['Authorization'] = base64.b64encode(auth_string)
        return r

I'm not sure that the various encodings are required, but that's how someone did it on github (https://github.com/skipjac/Zendesk-python-api/blob/master/zendesk-ticket-delete.py) so why not. I've tried it without the encoding too, of course - same result.

Here's the class and methods I'm using to test this:

class ZDStats(object):
    api_base = "https://mycompany.zendesk.com/api/v2/"

    def __init__(self,zd_auth):
        self.zd_auth = zd_auth # this is assumed to be a ZDTokenAuth object

    def testCredentials(self):
        zd_users_url = self.api_base + "users.json"
        zdreq = requests.get(zd_users_url, auth=self.zdauth)
        return zdreq

This is called with:

credentials = ZDTokenAuth(zd_username,zd_apitoken)
zd = ZDStats(credentials)
users = zd.testCredentials()
print(users.status_code)
print(users.text)

The status code I'm getting back is a 401, and the text is simply {"error":"Couldn't authenticate you."}. Clearly I'm doing something wrong here, but I don't think I know enough to know what it is I'm doing wrong, if that makes sense. Any ideas?

도움이 되었습니까?

해결책

What you're missing is the auth type. Your Authorization header should be created like this:

r.headers['Authorization'] = b"Basic " + base64.b64encode(auth_string)

You can also achieve the same passing by a tuple as auth parameter with:

requests.get(url, auth=(username+"/token", token))
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top