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!
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'
)
}
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.
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With