Skip to content
Advertisement

Can’t login my users, they don’t seem to be registering properly

I’m trying to login the users I registered in my registration view (where I get a 200 code that says POST request was successful) but I get “Unable to log in with provided credentials.” when I try to log them in. When I check in the shell with User.objects.all(), I only get my superuser back so I think the users are not being saved to the database. I don’t understand why this is happening so if anyone has an idea, it’d be appreciated.

Here’s the code.

Models:

from django.db import models, transaction
from django.conf import settings
from django.contrib.auth.models import BaseUserManager, AbstractUser


class UserManager(BaseUserManager):
    
    @transaction.atomic
    def create_user(self, email, username, password=False):
        
        if not email:
            raise ValueError('Users must have an email address')

        if not username:
            raise ValueError('Users must have an username')

        user = self.model(
            email=self.normalize_email(email),
            username=username,
        )
        user.set_password(password)
        user.save()

        return user

    def get_by_natural_key(self, username):
        return self.get(username=username)

    def create_superuser(self, username, password, email):
        
        user = self.create_user(
            username=username,
            email=email,
            password=password,
        )
        user.is_superuser = True
        user.save(using=self._db)
        return user


class User(AbstractUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,
        unique=True,
    )

    username = models.CharField(
        verbose_name= 'username',
        max_length= 50,
        unique=True,
    )

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    def __str__(self):
        return str(self.username)

Serializers:

from django.contrib.auth.models import User
from rest_framework import serializers
from backend.models import User
from django.contrib.sites.shortcuts import get_current_site
from django.db.models import Q
from rest_framework.validators import UniqueValidator
from rest_framework.authtoken.models import Token
from django.contrib.auth import authenticate, get_user_model

user = get_user_model()

class UserRegistrationSerializer(serializers.ModelSerializer):

    username = serializers.CharField(
        required=True,
        validators=[UniqueValidator(queryset=User.objects.all(),lookup='iexact')]
    )

    email = serializers.CharField(
        required=True,
        validators=[UniqueValidator(queryset=User.objects.all(),lookup='iexact')]
    )

    password = serializers.CharField(
        required=True,
        label="Password",
        style={'input_type': 'password'}
    )

    password_2 = serializers.CharField(
        required=True,
        label="Confirm Password",
        style={'input_type': 'password'}
    )

    class Meta:
        model = User
        fields = ['username', 'email', 'password', 'password_2',]

    def validate_password(self, value):
        if len(value) < 8:
            raise serializers.ValidationError(
                "Password should be at least 8 characters long.")
        return value

    def validate_password_2(self, value):
        data = self.get_initial()
        password = data.get('password')
        if password != value:
            raise serializers.ValidationError("Passwords don't match.")
        return value

    def validate_username(self, value):
        if User.objects.filter(username=value).exists():
            raise serializers.ValidationError("Username already exists.")
        return value

    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




class UserLoginSerializer(serializers.ModelSerializer):

    username = serializers.CharField(
        required=True,
        write_only=True,
    )

    token = serializers.CharField(
        allow_blank=True,
        read_only=True
    )

    password = serializers.CharField(
        required=True,
        write_only=True,
        style={'input_type': 'password'}
    )

    class Meta(object):
        model = User
        fields = ['username', 'password', 'token']

    def validate(self, data):
        username = data.get('username', None)
        password = data.get('password', None)

        if username and password:
            user = authenticate(request=self.context.get('request'),
                                username=username, password=password)
            if not user:
                msg = 'Unable to log in with provided credentials.'
                raise serializers.ValidationError(msg, code='authorization')
        else:
            msg = "Must include username and password."
            raise serializers.ValidationError(msg, code='authorization')

        data['user'] = user
        return data

   

Views:

from django.contrib.auth import get_user_model
from django.contrib.sites.shortcuts import get_current_site
from rest_framework import generics, permissions, status 
from rest_framework.authentication import TokenAuthentication
from rest_framework.response import Response

from backend.models import User 
from backend.serializers import UserLoginSerializer, UserRegistrationSerializer
from backend import serializers

from django.contrib.auth.decorators import login_required
from rest_framework.authtoken.models import Token

User = get_user_model()

class UserLoginAPIView(generics.CreateAPIView):

    permission_classes = (permissions.AllowAny, )
    serializer_class = serializers.UserLoginSerializer

    def post(self, request, *args, **kwargs):
        serializer = UserLoginSerializer(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({"status": status.HTTP_200_OK, "Token": token.key})

    

class UserRegistrationAPIView(generics.CreateAPIView):

    permission_classes = (permissions.AllowAny, )
    serializer_class = serializers.UserRegistrationSerializer

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid(raise_exception=True):
            return Response(serializer.data, status=status.HTTP_200_OK)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Advertisement

Answer

The issue was that I needed to add ‘user.set_password(validated_data[‘password’])’ right after the user. That solved it.

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
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement