[Fixed]-How to test authentication using REST Framework JWT?

27👍

Okay, the following seems to have solved the issue:

Instead of:

response = self.client.post("/auth/api/authenticated/", {}, Authorization='JWT ' + token)

I had to write:

response = self.client.post("/auth/api/authenticated/", {}, HTTP_AUTHORIZATION='JWT {}'.format(token))

Authentication works now through the Django test client as well.

4👍

Also keep in mind that when you create the user, you have to use the hashed version for the password. E.g.:

User(email='TestUser@email.io', password=make_password('TestPassword')))

(Using djangos password hashers)

While when calling /auth/api/get_token/ you have to use the clear case password. E.g.:

response = self.client.post("/auth/api/get_token/", {'email': 'TestUser@email.io', 'password': 'TestPassword'})

Took me a while to find out that the request responded 'non_field_errors': ['Unable to log in with provided credentials.'] because I didn’t use the hasher while creating the user.

👤seblat

1👍

It may be helpful to note that, when using JWT via OAuth2, the following code creates the authentication credentials:

self.client.post("/auth/api/authenticated/", {}, HTTP_AUTHORIZATION='Bearer {0}'.format(token))

Django Rest Framework, however, includes scaffolding to authenticate a request:
http://www.django-rest-framework.org/api-guide/testing/#forcing-authentication

Additionally, there are some interesting tests here:
https://github.com/jpadilla/django-jwt-auth/blob/master/tests/test_mixins.py

👤Brian

0👍

Create a basic method:

def create_jwt_token(user) -> str:
    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)
    return 'JWT ' + token

In your test, use it like this:

@classmethod
    def setUpTestData(cls):
        cls.valid_auth_headers = {
            "HTTP_AUTHORIZATION": UserTestUtils.create_jwt_token(cls.user)
        }

def test_valid_accepted_inputs_only(self):
        response = self.client.post(
            self.url,
            {
                "name": 'NewFarmName',
                "age": 2010
            },
            **self.valid_auth_headers,
        )

Leave a comment