When I test my POST route for Django Rest Framework API it returns a 401 not authenticated even though logged...
up vote
0
down vote
favorite
When I attempt to test my Create/POST route for my Django Rest Framework API I receive a response status code of 401 with the error detail telling me ErrorDetail(string=u'Authentication credentials were not provided.', code=u'not_authenticated')
. The weird thing is I Django tells me I'm authenticated when I check is is_authenticated.
Does anyone have an idea what might be causing this? All relevant code provided below.
# test_api.py
def authorise_user_and_test_is_authenticated(self, user_id):
"""
Log in user and test this is successful
"""
user = User.objects.get(pk=user_id)
self.client.login(username=user.username, password=user.password)
authorised_user = auth.get_user(self.client)
return self.assertTrue(user.is_authenticated())
def test_create_project(self):
'''
When given valid parameters a project is created.
'''
user = User.objects.get(username="user_001")
self.authorise_user_and_test_is_authenticated(user.id) # pass of authenication and auth testing to method, when tested with is_authenicated() it returns true.
response = self.client.post('/api/user/{0}/project/create/'.format(user.id),
json.dumps({"model_name": "POSTed Project",
"description": "Project tested by posting",
"shared_users": [2]
}),
content_type='application/json')
self.assertEqual(response.status_code, 201)
# views.py
class MyCreateView(generics.GenericAPIView):
pass
serializer_class = FerronPageCreateAndUpdateSerializer
def get_queryset(self):
return User.objects.filter(pk=self.kwargs.get('user'))
def post(self, request, format=None, **kwargs):
# This dictionary is used to ensure that the last_modified_by field is always updated on post to be the current user
print request.data
request_data = {
'user': request.user.id,
'model_name': request.data['model_name'],
'description': request.data['description'],
'last_modified_by': request.user.id,
'shared_users': request.data.getlist('shared_users', )
}
serializer = FerronPageCreateAndUpdateSerializer(data=request_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# settings.py
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
),
}
# url matcher
url(r'^user/(?P<user>d+)/project/create/$', MyCreateView.as_view(), name='create-project')
class FerronPageCreateAndUpdateSerializer(serializers.ModelSerializer):
shared_users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), read_only=False)
description = serializers.CharField(max_length=300, trim_whitespace=True, required=False, allow_blank=True)
class Meta:
model = Project
fields = [
'pk',
'user',
'data',
'model_name',
'description',
'created_at',
'date_modified',
'shared_users',
'last_modified_by'
]
python django django-rest-framework
|
show 3 more comments
up vote
0
down vote
favorite
When I attempt to test my Create/POST route for my Django Rest Framework API I receive a response status code of 401 with the error detail telling me ErrorDetail(string=u'Authentication credentials were not provided.', code=u'not_authenticated')
. The weird thing is I Django tells me I'm authenticated when I check is is_authenticated.
Does anyone have an idea what might be causing this? All relevant code provided below.
# test_api.py
def authorise_user_and_test_is_authenticated(self, user_id):
"""
Log in user and test this is successful
"""
user = User.objects.get(pk=user_id)
self.client.login(username=user.username, password=user.password)
authorised_user = auth.get_user(self.client)
return self.assertTrue(user.is_authenticated())
def test_create_project(self):
'''
When given valid parameters a project is created.
'''
user = User.objects.get(username="user_001")
self.authorise_user_and_test_is_authenticated(user.id) # pass of authenication and auth testing to method, when tested with is_authenicated() it returns true.
response = self.client.post('/api/user/{0}/project/create/'.format(user.id),
json.dumps({"model_name": "POSTed Project",
"description": "Project tested by posting",
"shared_users": [2]
}),
content_type='application/json')
self.assertEqual(response.status_code, 201)
# views.py
class MyCreateView(generics.GenericAPIView):
pass
serializer_class = FerronPageCreateAndUpdateSerializer
def get_queryset(self):
return User.objects.filter(pk=self.kwargs.get('user'))
def post(self, request, format=None, **kwargs):
# This dictionary is used to ensure that the last_modified_by field is always updated on post to be the current user
print request.data
request_data = {
'user': request.user.id,
'model_name': request.data['model_name'],
'description': request.data['description'],
'last_modified_by': request.user.id,
'shared_users': request.data.getlist('shared_users', )
}
serializer = FerronPageCreateAndUpdateSerializer(data=request_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# settings.py
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
),
}
# url matcher
url(r'^user/(?P<user>d+)/project/create/$', MyCreateView.as_view(), name='create-project')
class FerronPageCreateAndUpdateSerializer(serializers.ModelSerializer):
shared_users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), read_only=False)
description = serializers.CharField(max_length=300, trim_whitespace=True, required=False, allow_blank=True)
class Meta:
model = Project
fields = [
'pk',
'user',
'data',
'model_name',
'description',
'created_at',
'date_modified',
'shared_users',
'last_modified_by'
]
python django django-rest-framework
does the view working with normal API requests?
– JPG
Oct 28 at 2:13
rest does not have state .... you should auth another way (ie tokens attached to req) ... but basically that client was not authenticated...
– Joran Beasley
Oct 28 at 2:13
Hi Todd! Are you only having problems in the test? Either way the first step would be to removepass
from the first line after theMyCreateView
class declaration. Next is to share theself.authorise_user_and_test_is_authenticated
method or the whole test class if you can. Authentication in tests can be a pain so I've found usingself.client.force_authenticate(user=user)
in DRF tests to be an easy work around.
– Jacob Harding
Oct 28 at 5:12
Thanks all for your feedback so quickly. @JPG this works with normal api requests. @joran I had tried to access auth_token viauser.auth_token
but the key wasn't recognised? I'm not 100% sure on how to set that up.
– Todd Drinkwater
Oct 28 at 5:52
@JacobHarding Yes it only gives me problems during the test. However, when I've testing been doing get requests via the API that works fine. Have edited my question to include theself.authorise_user_and_test_is_authenticated
method now. I triedforce_authenticate
but seem my post seems to still return a 401.
– Todd Drinkwater
Oct 28 at 5:56
|
show 3 more comments
up vote
0
down vote
favorite
up vote
0
down vote
favorite
When I attempt to test my Create/POST route for my Django Rest Framework API I receive a response status code of 401 with the error detail telling me ErrorDetail(string=u'Authentication credentials were not provided.', code=u'not_authenticated')
. The weird thing is I Django tells me I'm authenticated when I check is is_authenticated.
Does anyone have an idea what might be causing this? All relevant code provided below.
# test_api.py
def authorise_user_and_test_is_authenticated(self, user_id):
"""
Log in user and test this is successful
"""
user = User.objects.get(pk=user_id)
self.client.login(username=user.username, password=user.password)
authorised_user = auth.get_user(self.client)
return self.assertTrue(user.is_authenticated())
def test_create_project(self):
'''
When given valid parameters a project is created.
'''
user = User.objects.get(username="user_001")
self.authorise_user_and_test_is_authenticated(user.id) # pass of authenication and auth testing to method, when tested with is_authenicated() it returns true.
response = self.client.post('/api/user/{0}/project/create/'.format(user.id),
json.dumps({"model_name": "POSTed Project",
"description": "Project tested by posting",
"shared_users": [2]
}),
content_type='application/json')
self.assertEqual(response.status_code, 201)
# views.py
class MyCreateView(generics.GenericAPIView):
pass
serializer_class = FerronPageCreateAndUpdateSerializer
def get_queryset(self):
return User.objects.filter(pk=self.kwargs.get('user'))
def post(self, request, format=None, **kwargs):
# This dictionary is used to ensure that the last_modified_by field is always updated on post to be the current user
print request.data
request_data = {
'user': request.user.id,
'model_name': request.data['model_name'],
'description': request.data['description'],
'last_modified_by': request.user.id,
'shared_users': request.data.getlist('shared_users', )
}
serializer = FerronPageCreateAndUpdateSerializer(data=request_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# settings.py
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
),
}
# url matcher
url(r'^user/(?P<user>d+)/project/create/$', MyCreateView.as_view(), name='create-project')
class FerronPageCreateAndUpdateSerializer(serializers.ModelSerializer):
shared_users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), read_only=False)
description = serializers.CharField(max_length=300, trim_whitespace=True, required=False, allow_blank=True)
class Meta:
model = Project
fields = [
'pk',
'user',
'data',
'model_name',
'description',
'created_at',
'date_modified',
'shared_users',
'last_modified_by'
]
python django django-rest-framework
When I attempt to test my Create/POST route for my Django Rest Framework API I receive a response status code of 401 with the error detail telling me ErrorDetail(string=u'Authentication credentials were not provided.', code=u'not_authenticated')
. The weird thing is I Django tells me I'm authenticated when I check is is_authenticated.
Does anyone have an idea what might be causing this? All relevant code provided below.
# test_api.py
def authorise_user_and_test_is_authenticated(self, user_id):
"""
Log in user and test this is successful
"""
user = User.objects.get(pk=user_id)
self.client.login(username=user.username, password=user.password)
authorised_user = auth.get_user(self.client)
return self.assertTrue(user.is_authenticated())
def test_create_project(self):
'''
When given valid parameters a project is created.
'''
user = User.objects.get(username="user_001")
self.authorise_user_and_test_is_authenticated(user.id) # pass of authenication and auth testing to method, when tested with is_authenicated() it returns true.
response = self.client.post('/api/user/{0}/project/create/'.format(user.id),
json.dumps({"model_name": "POSTed Project",
"description": "Project tested by posting",
"shared_users": [2]
}),
content_type='application/json')
self.assertEqual(response.status_code, 201)
# views.py
class MyCreateView(generics.GenericAPIView):
pass
serializer_class = FerronPageCreateAndUpdateSerializer
def get_queryset(self):
return User.objects.filter(pk=self.kwargs.get('user'))
def post(self, request, format=None, **kwargs):
# This dictionary is used to ensure that the last_modified_by field is always updated on post to be the current user
print request.data
request_data = {
'user': request.user.id,
'model_name': request.data['model_name'],
'description': request.data['description'],
'last_modified_by': request.user.id,
'shared_users': request.data.getlist('shared_users', )
}
serializer = FerronPageCreateAndUpdateSerializer(data=request_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# settings.py
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
),
}
# url matcher
url(r'^user/(?P<user>d+)/project/create/$', MyCreateView.as_view(), name='create-project')
class FerronPageCreateAndUpdateSerializer(serializers.ModelSerializer):
shared_users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), read_only=False)
description = serializers.CharField(max_length=300, trim_whitespace=True, required=False, allow_blank=True)
class Meta:
model = Project
fields = [
'pk',
'user',
'data',
'model_name',
'description',
'created_at',
'date_modified',
'shared_users',
'last_modified_by'
]
python django django-rest-framework
python django django-rest-framework
edited Oct 28 at 5:25
asked Oct 28 at 2:09
Todd Drinkwater
5219
5219
does the view working with normal API requests?
– JPG
Oct 28 at 2:13
rest does not have state .... you should auth another way (ie tokens attached to req) ... but basically that client was not authenticated...
– Joran Beasley
Oct 28 at 2:13
Hi Todd! Are you only having problems in the test? Either way the first step would be to removepass
from the first line after theMyCreateView
class declaration. Next is to share theself.authorise_user_and_test_is_authenticated
method or the whole test class if you can. Authentication in tests can be a pain so I've found usingself.client.force_authenticate(user=user)
in DRF tests to be an easy work around.
– Jacob Harding
Oct 28 at 5:12
Thanks all for your feedback so quickly. @JPG this works with normal api requests. @joran I had tried to access auth_token viauser.auth_token
but the key wasn't recognised? I'm not 100% sure on how to set that up.
– Todd Drinkwater
Oct 28 at 5:52
@JacobHarding Yes it only gives me problems during the test. However, when I've testing been doing get requests via the API that works fine. Have edited my question to include theself.authorise_user_and_test_is_authenticated
method now. I triedforce_authenticate
but seem my post seems to still return a 401.
– Todd Drinkwater
Oct 28 at 5:56
|
show 3 more comments
does the view working with normal API requests?
– JPG
Oct 28 at 2:13
rest does not have state .... you should auth another way (ie tokens attached to req) ... but basically that client was not authenticated...
– Joran Beasley
Oct 28 at 2:13
Hi Todd! Are you only having problems in the test? Either way the first step would be to removepass
from the first line after theMyCreateView
class declaration. Next is to share theself.authorise_user_and_test_is_authenticated
method or the whole test class if you can. Authentication in tests can be a pain so I've found usingself.client.force_authenticate(user=user)
in DRF tests to be an easy work around.
– Jacob Harding
Oct 28 at 5:12
Thanks all for your feedback so quickly. @JPG this works with normal api requests. @joran I had tried to access auth_token viauser.auth_token
but the key wasn't recognised? I'm not 100% sure on how to set that up.
– Todd Drinkwater
Oct 28 at 5:52
@JacobHarding Yes it only gives me problems during the test. However, when I've testing been doing get requests via the API that works fine. Have edited my question to include theself.authorise_user_and_test_is_authenticated
method now. I triedforce_authenticate
but seem my post seems to still return a 401.
– Todd Drinkwater
Oct 28 at 5:56
does the view working with normal API requests?
– JPG
Oct 28 at 2:13
does the view working with normal API requests?
– JPG
Oct 28 at 2:13
rest does not have state .... you should auth another way (ie tokens attached to req) ... but basically that client was not authenticated...
– Joran Beasley
Oct 28 at 2:13
rest does not have state .... you should auth another way (ie tokens attached to req) ... but basically that client was not authenticated...
– Joran Beasley
Oct 28 at 2:13
Hi Todd! Are you only having problems in the test? Either way the first step would be to remove
pass
from the first line after the MyCreateView
class declaration. Next is to share the self.authorise_user_and_test_is_authenticated
method or the whole test class if you can. Authentication in tests can be a pain so I've found using self.client.force_authenticate(user=user)
in DRF tests to be an easy work around.– Jacob Harding
Oct 28 at 5:12
Hi Todd! Are you only having problems in the test? Either way the first step would be to remove
pass
from the first line after the MyCreateView
class declaration. Next is to share the self.authorise_user_and_test_is_authenticated
method or the whole test class if you can. Authentication in tests can be a pain so I've found using self.client.force_authenticate(user=user)
in DRF tests to be an easy work around.– Jacob Harding
Oct 28 at 5:12
Thanks all for your feedback so quickly. @JPG this works with normal api requests. @joran I had tried to access auth_token via
user.auth_token
but the key wasn't recognised? I'm not 100% sure on how to set that up.– Todd Drinkwater
Oct 28 at 5:52
Thanks all for your feedback so quickly. @JPG this works with normal api requests. @joran I had tried to access auth_token via
user.auth_token
but the key wasn't recognised? I'm not 100% sure on how to set that up.– Todd Drinkwater
Oct 28 at 5:52
@JacobHarding Yes it only gives me problems during the test. However, when I've testing been doing get requests via the API that works fine. Have edited my question to include the
self.authorise_user_and_test_is_authenticated
method now. I tried force_authenticate
but seem my post seems to still return a 401.– Todd Drinkwater
Oct 28 at 5:56
@JacobHarding Yes it only gives me problems during the test. However, when I've testing been doing get requests via the API that works fine. Have edited my question to include the
self.authorise_user_and_test_is_authenticated
method now. I tried force_authenticate
but seem my post seems to still return a 401.– Todd Drinkwater
Oct 28 at 5:56
|
show 3 more comments
1 Answer
1
active
oldest
votes
up vote
0
down vote
Turn's out the issue was here self.client.login(username=user.username, password=user.password)
inside the authorise_user_and_test_is_authenticated(self, user_id)
method.
The problem was that I was using the password an instance of a user I had already created. This meant when I gave the argument password=user.password
, I was trying to log in using a password that had already been hashed. What I needed to do instead was log in with the original unhashed version of the password e.g. password='openseasame'
.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Turn's out the issue was here self.client.login(username=user.username, password=user.password)
inside the authorise_user_and_test_is_authenticated(self, user_id)
method.
The problem was that I was using the password an instance of a user I had already created. This meant when I gave the argument password=user.password
, I was trying to log in using a password that had already been hashed. What I needed to do instead was log in with the original unhashed version of the password e.g. password='openseasame'
.
add a comment |
up vote
0
down vote
Turn's out the issue was here self.client.login(username=user.username, password=user.password)
inside the authorise_user_and_test_is_authenticated(self, user_id)
method.
The problem was that I was using the password an instance of a user I had already created. This meant when I gave the argument password=user.password
, I was trying to log in using a password that had already been hashed. What I needed to do instead was log in with the original unhashed version of the password e.g. password='openseasame'
.
add a comment |
up vote
0
down vote
up vote
0
down vote
Turn's out the issue was here self.client.login(username=user.username, password=user.password)
inside the authorise_user_and_test_is_authenticated(self, user_id)
method.
The problem was that I was using the password an instance of a user I had already created. This meant when I gave the argument password=user.password
, I was trying to log in using a password that had already been hashed. What I needed to do instead was log in with the original unhashed version of the password e.g. password='openseasame'
.
Turn's out the issue was here self.client.login(username=user.username, password=user.password)
inside the authorise_user_and_test_is_authenticated(self, user_id)
method.
The problem was that I was using the password an instance of a user I had already created. This meant when I gave the argument password=user.password
, I was trying to log in using a password that had already been hashed. What I needed to do instead was log in with the original unhashed version of the password e.g. password='openseasame'
.
answered Nov 11 at 9:03
Todd Drinkwater
5219
5219
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53027815%2fwhen-i-test-my-post-route-for-django-rest-framework-api-it-returns-a-401-not-aut%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
does the view working with normal API requests?
– JPG
Oct 28 at 2:13
rest does not have state .... you should auth another way (ie tokens attached to req) ... but basically that client was not authenticated...
– Joran Beasley
Oct 28 at 2:13
Hi Todd! Are you only having problems in the test? Either way the first step would be to remove
pass
from the first line after theMyCreateView
class declaration. Next is to share theself.authorise_user_and_test_is_authenticated
method or the whole test class if you can. Authentication in tests can be a pain so I've found usingself.client.force_authenticate(user=user)
in DRF tests to be an easy work around.– Jacob Harding
Oct 28 at 5:12
Thanks all for your feedback so quickly. @JPG this works with normal api requests. @joran I had tried to access auth_token via
user.auth_token
but the key wasn't recognised? I'm not 100% sure on how to set that up.– Todd Drinkwater
Oct 28 at 5:52
@JacobHarding Yes it only gives me problems during the test. However, when I've testing been doing get requests via the API that works fine. Have edited my question to include the
self.authorise_user_and_test_is_authenticated
method now. I triedforce_authenticate
but seem my post seems to still return a 401.– Todd Drinkwater
Oct 28 at 5:56