I have implemented token based authentication using rest_framework, every thing is working fine as of now but I have one question that if I am sending user-name and password in header using basic-auth then why am I required to send user-name and password with payload. When I sending request containing payload with user-name and password in body section with out user-name and password in header of request, I am getting following as response:
{
"detail": "CSRF Failed: CSRF token missing or incorrect."
}
while I am sending user-name and password in header with out sending user-name and password with payload, I am getting following response:
{
"detail": "Invalid username/password."
}
Why am I required to send user-name and password in header section while I am sending it with payload. I am not quite sure about the concept. Could anyone please explain and show me the right way to do it. I have used this reference.
Following is my code: authuser.py
"""Authentication classes for Django Rest Framework.
Classes:
ExpiringTokenAuthentication: Authentication using extended authtoken model.
"""
from rest_framework import exceptions
from rest_framework.authentication import TokenAuthentication
from rest_framework_expiring_authtoken.models import ExpiringToken
class ExpiringTokenAuthentication(TokenAuthentication):
"""
Extends default token auth to have time-based expiration.
Based on http://stackoverflow.com/questions/14567586/
"""
model = ExpiringToken
def authenticate_credentials(self, key):
"""Attempt token authentication using the provided key."""
if key == "2572e6dbe3b2e150764cd72712713b2975785197":
token = self.model.objects.get(key=key)
else:
try:
token = self.model.objects.get(key=key)
except self.model.DoesNotExist:
raise exceptions.AuthenticationFailed('Invalid token')
if not token.user.is_active:
raise exceptions.AuthenticationFailed('User inactive or deleted')
#if token.expired():
# raise exceptions.AuthenticationFailed('Token has expired')
return (token.user_id, token)
view .py
class ObtainExpiringAuthToken(ObtainAuthToken):
"""View enabling username/password exchange for expiring token."""
model = ExpiringToken
def post(self, request):
try:
payload=json.loads(request.body)
except:
return Response({'success':False,'message':'Invalid Payload.'})
"""Respond to POSTed username/password with token."""
serializer = AuthTokenSerializer(data=request.data)
if serializer.is_valid():
token, _ = ExpiringToken.objects.get_or_create(
user=serializer.validated_data['user']
)
if token.expired():
# If the token is expired, generate a new one.
token.delete()
token = ExpiringToken.objects.create(
user=serializer.validated_data['user']
)
try:
user = User.objects.get(id=token.user_id)
except:
return Response({'success':False,'message':'User does not exists.'})
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
obtain_expiring_auth_token = ObtainExpiringAuthToken.as_view()
models.py :
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
class ExpiringToken(Token):
"""Extend Token to add an expired method."""
class Meta(object):
proxy = True
def expired(self):
"""Return boolean indicating token expiration."""
now = timezone.now()
#if self.created < now - token_settings.EXPIRING_TOKEN_LIFESPAN:
# return True
return True
settings.py:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
)
}