djangonaut
djangonaut

Reputation: 7778

Python: Invalid HTTP basic authentication header with long base64 string

I tried to login my django-rest-framework test client via HTTP Basic authentication to gain a REST-API token. But had to find out that it fails once my randomly generated username and password is too long:

def login_client(self):
    uid = uuid.uuid4().hex
    user = User.objects.create(username=uid, email="{}@foo.de".format(uid))
    user.set_password(uid)
    user.save()
    self.client.credentials(HTTP_AUTHORIZATION=self.get_knox_auth_header(uid, uid))
    response = self.client.post(reverse("knox_login"))
    print response.content.data["token"]

def get_knox_auth_header(self, username, password):
    return "Basic {}".format("{}:{}".format(username, password).encode("base64"))

Header looks like:

Basic MTAyZDc2OTJjY2E5NGY0NmFmNThkODNmNDc5NTc6MTAyZDc2OTJjY2E5NGY0NmFmNThkODNmNDc5
NTc=

Response:

{"detail":"Invalid basic header. Credentials string should not contain spaces."}

Upvotes: 1

Views: 2129

Answers (1)

djangonaut
djangonaut

Reputation: 7778

Reason is that str.encode automatically adds linebreaks to long base64 strings. The code works well when you force a shorter input string, e.g. uid = uuid.uuid4().hex[:28]

To avoid the linebreaks it's better to use:

import base64
"Basic {}".format(base64.b64encode("{}:{}".format(username, password)))

Upvotes: 2

Related Questions