Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django rest framework Authentcation Testing

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'
    )
}
like image 231
aslheyrr Avatar asked Jan 30 '15 04:01

aslheyrr


People also ask

Which authentication is best in Django REST framework?

JSON Web Token Authentication Unlike the built-in TokenAuthentication scheme, JWT Authentication doesn't need to use a database to validate a token. A package for JWT authentication is djangorestframework-simplejwt which provides some features as well as a pluggable token blacklist app.

What is basic authentication in Django REST framework?

Basic Authentication in Django REST Framework uses HTTP Basic Authentication. It is generally appropriate for testing. The REST framework will attempt to authenticate the Basic Authentication class and set the returned values to request. user and request.


2 Answers

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

like image 54
Yishai Landau Avatar answered Oct 05 '22 02:10

Yishai Landau


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.

like image 43
Jamie Counsell Avatar answered Oct 05 '22 02:10

Jamie Counsell