Paymahn Moghadasian
Paymahn Moghadasian

Reputation: 10339

Authenticate in Django test client with headers

I've overridden the ModelBackend in my django app. My overridden model backend requires that headers be present in the request to log in the user.

HEADER = 'testing'
class TestingModelBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        testing_header_value = None
        if request is not None and request.META is not None:
            testing_header_value = request.META.get(HEADER, None)

        if username is None:
            username = kwargs.get(User.USERNAME_FIELD)
        try:
            user = User.objects.get_by_natural_key(username, testing_header_value)
        except User.DoesNotExist:
            # Run the default password hasher once to reduce the timing
            # difference between an existing and a nonexistent user (#20760).
            User().set_password(password)
        else:
            # now validate password and whether the user is active
            if user.check_password(password) and self.user_can_authenticate(user):
                return user

This works perfectly in non test scenarios. However, when I test I'm running into a problem of passing headers with the test client.

The Django test client has a login method but it doesn't pass the request when authenticating which means that my model backend can't function correctly - I can't pass the header I need to. Note that one of the parameters in the authenticate function is the current request.

I see that I can use force_login but that seems a little hack-y. What is the correct way to do this? I suspect subclassing the default test client and overriding the login method might be best but I'm not sure.

Upvotes: 0

Views: 235

Answers (1)

Dmitry Fedotkin
Dmitry Fedotkin

Reputation: 272

I believe force_login() is the best thing to use in your case.

Upvotes: 1

Related Questions