Andrew Daunais
Andrew Daunais

Reputation: 1

Django/knox backend login failing even when given proper username and password

I'm building user authentication in Django using the built-in user model and knox token authentication. Through postman, I'm able to create a new user which properly returns the username and a unique token for that user. However, when I attempt to hit my login path with correct username and password information, it returns a 400 Bad Request along with my validation error message "Incorrect Credentials." Any idea why this might be happening?

Below is my login serializer, api, and url paths.

# Login Serializer in serializers.py

from rest_framework import serializers
from django.contrib.auth.models import User
from django.contrib.auth import authenticate

class LoginSerializer(serializers.Serializer):
    username = serializers.CharField()
    password = serializers.CharField()

    def validate(self, data):
        user = authenticate(**data)
        if user and user.is_active:
            return user
        raise serializers.ValidationError('Incorrect Credentials')
# Login API in api.py

from rest_framework import generics
from rest_framework.response import Response
from knox.models import AuthToken
from .serializers import LoginSerializer

class LoginAPI(generics.GenericAPIView):
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data
        return Response({
            "user": UserSerializer(user, context=self.get_serializer_context()).data,
            "token": AuthToken.objects.create(user)[1]
        })
from django.urls import path, include
from .api import RegisterAPI, LoginAPI, UserAPI
from knox import views as knox_views

urlpatterns = {
    path('auth', include('knox.urls')),
    path('auth/register', RegisterAPI.as_view()),
    path('auth/login', LoginAPI.as_view()),
    path('auth/user', UserAPI.as_view()),
    path('auth/logout', knox_views.LogoutView.as_view(), name='knox_logout'),
}

I will note that I tried moving the include('knox.urls') piece to the bottom of my url paths in case any similar path name issues were occurring and still received the same issue.

Upvotes: 0

Views: 1432

Answers (1)

Ruslan Yakushev
Ruslan Yakushev

Reputation: 11

I know it's pretty late, but if it's going to help someone I'll be glad. The solution to this is to change the rest framework default authentication class. If you're using knox to generate your tokens, then adding 'knox.auth.TokenAuthentication', default authentication class to the REST_FRAMEWORK variable should solve the problem. The variable is located in your settings.py file. You'll end up with something like this:

   REST_FRAMEWORK = {
       'DEFAULT_AUTHENTICATION_CLASSES': (
           'knox.auth.TokenAuthentication',
       ),
   }

Upvotes: 1

Related Questions