Reputation: 3628
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?
Upvotes: 3
Views: 3404
Reputation: 69012
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))
Upvotes: 13