6

I'm trying to make a test case for authentication with JWT, in this case with django-rest-framework-jwt, then, with curl I get the next, so:

curl -X POST -d "[email protected]&password=testing" http://localhost:8000/api/auth/token/

Get:

{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjo0LCJlbWFpbCI6InRlc3R1c2VyQHRlc3QuY29tIiwiZXhwIjoxNDIyNTkxMTQ5LCJ1c2VybmFtZSI6InRlc3R1c2VyQHRlc3QuY29tIn0.OT8ggcZYWxcbSy0Vv8u5PA3QISIdarNXTVuvu4QQjnw"}

But, when I run my test case:

class BaseTestCase(TestCase):

    def setUp(self):
        self.csrf_client = APIClient(enforce_csrf_checks=True)
        self.email = '[email protected]'
        self.name = 'test user'
        self.password = 'testing'
        user = Usuario.objects.create_user(email=self.email, name=self.name, password=self.password)
        user.save()
        self.data = {
            'email': self.email,
            'password': self.password
        }
        self.url = '/api/auth/token/'


class ObtainJSONWebTokenTests(BaseTestCase):

    def test_jwt_login_json(self):
        """
        Ensure JWT login view using JSON POST works.
        """
        client = APIClient(enforce_csrf_checks=True)

        response = client.post(self.url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK, response.data)

    def test_jwt_login_json_incomplete_creds(self):
        """
        Ensure JWT login view using JSON POST fails
        if incomplete credentials are used.
        """
        client = APIClient(enforce_csrf_checks=True)

        self.data = {
            'email': self.email
        }
        response = client.post(self.url, self.data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.data)

I got this:

Creating test database for alias 'default'...
F.
======================================================================
FAIL: test_jwt_login_json (user.tests.ObtainJSONWebTokenTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/rizotas/Proyects/django/src/rescue/user/tests.py", line 34, in test_jwt_login_json
    self.assertEqual(response.status_code, status.HTTP_200_OK, response.data)
AssertionError: 400 != 200 : ReturnDict([('non_field_errors', ['Unable to login with provided credentials.'])])

----------------------------------------------------------------------
Ran 2 tests in 0.374s

FAILED (failures=1)
Destroying test database for alias 'default'...

any idea?

Thanks so much!

Update:

my settings

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    #'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'debug_toolbar',
    'debug_panel',
    ...)


REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
       'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',
    'TEST_REQUEST_RENDERER_CLASSES': (
        'rest_framework.renderers.MultiPartRenderer',
        'rest_framework.renderers.JSONRenderer',
        #'rest_framework.renderers.YAMLRenderer'
    )
}
1
  • hey any progress/solution on this? I'm in the exact same boat Commented Mar 28, 2015 at 14:38

3 Answers 3

5

Had the same problem. Apparently, when you create a user using the default serializer and the path localhost:8000/users/, the password is not saved. Confirm that by running a curl request and then querying the database.

Following instructions from this site: http://www.django-rest-framework.org/api-guide/serializers/#hyperlinkedmodelserializer here's my new UserSerializer class:

class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
    model = User
    fields = ('username', 'first_name', 'last_name', 'email', 'password')
    extra_kwargs = {'password': {'write_only': True}}

def create(self, validated_data):
    user = User(
        email=validated_data['email'],
        username=validated_data['username']
    )
    user.set_password(validated_data['password'])
    user.save()
    return user

This code assumes both username and email are required fields. Obviously, this can be changed according to your own business-logic

Hope this helps,

Yishai

Sign up to request clarification or add additional context in comments.

Comments

1

I'm not at a computer prepared to test this, but I believe Django uses a separate database when testing, that is created and destroyed at the start and end of the tests, respectively. You must create the user inside the test if you haven't already, then attempt to log in with it. The test database contains no user authenticated by those credentials.

1 Comment

yes, but user is created, look: if I add print(User.objects.get(email=self.email)) to test_jwt_login_json got 1 - test user
0

In your cURL example, you're not passing in JSON, but instead a standard POST body. Looks like the view that '/api/auth/token/' resolves to isn't accepting JSON. This cURL command should fail in the same way:

curl -H "Content-Type: application/json" -d '{"email":"xyz","password":"xyz"}' http://localhost:8000/api/auth/token/

It might help if you posted your view code.

4 Comments

I try with curl -H "Content-Type: application/json" ..... and works, but when I try curl -H "Authorization: JWT eyJhb...." http://localhost:8000/<protected> get {"detail":"Authentication credentials were not provided."}. My settings are with REST framework JWT Auth
Sounds like you haven't configured djangorestframework-jwt correctly. It might help if you posted your settings.
I just noticed your update to your question. You're not passing the password in to self.client.post, only the username. Have you tried that already?
I have added my settings

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.