Django Rest Framework – invalid credentials – can not Login via Postman
Question:
I’m working on web app where you can register and login via Postman. Register is working fine. Here is serializer.py
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import authenticate
class RegisterSerializer(serializers.Serializer):
first_name = serializers.CharField()
last_name = serializers.CharField()
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
if User.objects.filter(username=data["username"]).exists():
raise serializers.ValidationError("username is already taken")
return data
def create(self, validated_data):
user = User.objects.create(first_name=validated_data["first_name"],
last_name=validated_data["last_name"],
username=validated_data["username"].lower()
)
user.set_password(validated_data["password"])
return validated_data
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
if not User.objects.filter(username=data["username"]).exists():
raise serializers.ValidationError("account not found")
return data
def get_jwt_token(self, data):
user = authenticate(username=data["username"], password=data["password"])
if not user:
return {"message": "invalid credentials", "data": {}}
refresh = RefreshToken.for_user(user)
return {
"message": "login success",
"data": {"token": {"refresh": str(refresh),
"access": str(refresh.access_token)}}}
Here is views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import RegisterSerializer, LoginSerializer
from rest_framework import status
class RegisterView(APIView):
def post(self, request):
try:
data = request.data
serializer = RegisterSerializer(data=data)
if not serializer.is_valid():
return Response ({
"data" : serializer.errors,
"message" : "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
serializer.save()
return Response({
"data" : {},
"message" : "user created successfully",
}, status=status.HTTP_201_CREATED)
except Exception as e:
print(e)
return Response({
"data" : {},
"message" : "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
class LoginView(APIView):
def post(self,request):
try:
data = request.data
serializer = LoginSerializer(data=data)
if not serializer.is_valid():
return Response({
"data": serializer.errors,
"message": "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
response = serializer.get_jwt_token(serializer.data)
return Response(response, status=status.HTTP_200_OK)
except Exception as e:
print(e)
return Response({
"data" : {},
"message" : "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
In Postman Register works fine
But if I want to login:
I don’t know why it is not working. I read jwt documentation and I think that I have it right.
I don’t have any more screenshot. If you want see rest of the code I can post it.
Answers:
The problem seems to be with this line of code
user = authenticate(username=data["username"], password=data["password"])
put a breakpoint and look if the values being passed match the values in your database.
Make sure that the AUTHENTICATION_BACKENDS
setting in your Django settings includes the django.contrib.auth.backends.ModelBackend
backend. If this setting is missing or incorrect, the authenticate function may not work properly.
You should also check the value of the data dictionary to make sure that the username
and password
fields are being passed correctly from the request. You can print out the data dictionary or use a debugger to inspect its contents.
In addition to using a breakpoint, you could also try logging the return value of the authenticate function to see if it is returning a valid user object. If the authenticate function is not able to authenticate the user, it will return None.
If the authenticate function is returning None
, you should check that the password for the user is correctly hashed and stored in the database. If the password is not hashed correctly, the authenticate function will not be able to match it against the stored password hash.
I’m working on web app where you can register and login via Postman. Register is working fine. Here is serializer.py
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth import authenticate
class RegisterSerializer(serializers.Serializer):
first_name = serializers.CharField()
last_name = serializers.CharField()
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
if User.objects.filter(username=data["username"]).exists():
raise serializers.ValidationError("username is already taken")
return data
def create(self, validated_data):
user = User.objects.create(first_name=validated_data["first_name"],
last_name=validated_data["last_name"],
username=validated_data["username"].lower()
)
user.set_password(validated_data["password"])
return validated_data
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
if not User.objects.filter(username=data["username"]).exists():
raise serializers.ValidationError("account not found")
return data
def get_jwt_token(self, data):
user = authenticate(username=data["username"], password=data["password"])
if not user:
return {"message": "invalid credentials", "data": {}}
refresh = RefreshToken.for_user(user)
return {
"message": "login success",
"data": {"token": {"refresh": str(refresh),
"access": str(refresh.access_token)}}}
Here is views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializer import RegisterSerializer, LoginSerializer
from rest_framework import status
class RegisterView(APIView):
def post(self, request):
try:
data = request.data
serializer = RegisterSerializer(data=data)
if not serializer.is_valid():
return Response ({
"data" : serializer.errors,
"message" : "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
serializer.save()
return Response({
"data" : {},
"message" : "user created successfully",
}, status=status.HTTP_201_CREATED)
except Exception as e:
print(e)
return Response({
"data" : {},
"message" : "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
class LoginView(APIView):
def post(self,request):
try:
data = request.data
serializer = LoginSerializer(data=data)
if not serializer.is_valid():
return Response({
"data": serializer.errors,
"message": "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
response = serializer.get_jwt_token(serializer.data)
return Response(response, status=status.HTTP_200_OK)
except Exception as e:
print(e)
return Response({
"data" : {},
"message" : "something went wrong",
}, status=status.HTTP_400_BAD_REQUEST)
In Postman Register works fine
But if I want to login:
I don’t know why it is not working. I read jwt documentation and I think that I have it right.
I don’t have any more screenshot. If you want see rest of the code I can post it.
The problem seems to be with this line of code
user = authenticate(username=data["username"], password=data["password"])
put a breakpoint and look if the values being passed match the values in your database.
Make sure that the AUTHENTICATION_BACKENDS
setting in your Django settings includes the django.contrib.auth.backends.ModelBackend
backend. If this setting is missing or incorrect, the authenticate function may not work properly.
You should also check the value of the data dictionary to make sure that the username
and password
fields are being passed correctly from the request. You can print out the data dictionary or use a debugger to inspect its contents.
In addition to using a breakpoint, you could also try logging the return value of the authenticate function to see if it is returning a valid user object. If the authenticate function is not able to authenticate the user, it will return None.
If the authenticate function is returning None
, you should check that the password for the user is correctly hashed and stored in the database. If the password is not hashed correctly, the authenticate function will not be able to match it against the stored password hash.