David Glass
David Glass

Reputation: 3178

Django Authenticate returns None

I have the following code snippet:

user = User(username='[email protected]',email='[email protected]')
user.set_password('pass')
user.save()
u = authenticate(username='[email protected]', password='pass') #this always returns None!!!

The problem is, u is always None. I've followed code samples on other stack overflow posts and have narrowed it down to the above lines.

Any ideas as to what might be happening?

Upvotes: 23

Views: 26583

Answers (12)

Ashwin Kavale
Ashwin Kavale

Reputation: 1

I faced similar issue. After setting the user status to Active worked for me in my custom user account table.

Upvotes: 0

José Farias
José Farias

Reputation: 1

For those currently experiencing the issue and have not been able to solve it, it is due to the current Django configurations. You cannot ignore the messages or recommendations regarding the username and password, especially the password, which should not be the same or similar to the username, must contain at least 8 characters, and not all characters should be numeric. In short, make sure to read all of that carefully; if you do it correctly, authentication works, but if you do it incorrectly, it fails. Django does not warn you of the error, but it is always good to use form.is_valid(). A valid password would be 'badluck123'. If it helps anyone, I am providing my code:

def Registro(request):
if request.method == 'GET':
    return render(request, 'pages/registrarse.html', {'form': UserCreationForm})
else:
    form = UserCreationForm(request.POST)
    if form.is_valid():
        try:
            usuario = form.save()
            return render(request, 'pages/registrarse.html', {
                'form': UserCreationForm(),
                'mensaje': 'Usuario Creado'
            })
        except IntegrityError:
            return render(request, 'pages/registrarse.html', {
                'form': form,
                'error': 'El usuario ya existe'
            })
    else:
        return render(request, 'pages/registrarse.html', {
            'form': form,
            'error': 'Las contraseñas no coinciden'
        })

Upvotes: 0

Pedram
Pedram

Reputation: 684

In Django 5 if I create a user by this method:

User(username='jojo', password='pass').save()

If I check Django admin page:

enter image description here

No wonder authenticate returns None for this user. The password and the user don't match.

Instead, you can create your user by this method:

User.objects.create_user(username='jojo2', password='pass')

Also and interestingly if I do:

User(username='jojo3').set_password('pass').save()

It works fine and the raw password is stored by hashing algorithms correctly (in django 5).

Upvotes: 0

miloshIra
miloshIra

Reputation: 63

I puzzled with this problem for four days, and the above answers didn't help. The problem was that I, as you, was using the user.save() and I could not see what the problem was, but then I looked at it with debug eyes, and it turns out that if you use user.save() it messes with the hashing of the password somehow, don't ask me how I don't know. So I worked around it by using the user.create() method that Django provides, worked like a charm:

@api_view(['POST'])
def create_user(request):
    new_user = UserSerializer(data=request.data)
    if new_user.is_valid():
        user_saved = new_user.create(request.data)
        return Response('User {} created'.format(user_saved.username), 
                                           status=status.HTTP_200_OK)
    else:
        return Response('User not created', status=status.HTTP_200_OK)

I used something like this, but you can do as you wish just use the user.create().

Upvotes: 1

leanh
leanh

Reputation: 21

You have to check whether user is active? If not, you only set active for user in admin panel, or set when creating user by adding the following line to user model:

is_active = models.BooleanField(default=True)

Upvotes: 2

Akhil S
Akhil S

Reputation: 1171

As most of them suggested if we create the user's using User.objects.create_user(**validated_data) this will hash the raw password and store the hashed password. In-case if you you are using User model serializers to validate and create users, it is required to override the serializer method like this

class UserSerializers(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = "__all__"

    # this is the method responsible for insertion of data with hashed password
    def create(self, validated_data):
        return User.objects.create_user(**validated_data)

Upvotes: 0

Julio Marins
Julio Marins

Reputation: 10639

set_password is a misleading method, it doesn't save the password on the user table. You need to call user.save() in order for it to work on your flow

Upvotes: 2

sl mahis
sl mahis

Reputation: 53

Also check that you have the right username/password combo. sometimes the one that is created from the createsuperuser command is different than a username you would typically use.

Upvotes: 0

algometrix
algometrix

Reputation: 3992

In settings.py, add

AUTH_USER_MODEL = your custom user class

e.g if django app name is office and custom user class is Account then

AUTH_USER_MODEL = 'office.Account'

Upvotes: 3

Ramast
Ramast

Reputation: 7709

Put something like this in your settings

#Authentication backends
AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.ModelBackend',
    )

or if you are using userena for your accounts

#Authentication backends
AUTHENTICATION_BACKENDS = (
    'userena.backends.UserenaAuthenticationBackend',
    'guardian.backends.ObjectPermissionBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Upvotes: 12

David Glass
David Glass

Reputation: 3178

Interestingly enough, check_password returns True in the following:

eml = "[email protected]"
pw = "pass"
uname = 'w2'
user = User.objects.create_user(uname,eml,pw)
user.save()
log.debug("Password check passes?")
log.debug(user.check_password(pw)) # Logs True!!!
user = authenticate(username=uname, password=pw)

Upvotes: 9

H H H
H H H

Reputation: 529

Why don't you create a user like this:

user = User.objects.create_user( username="whatever", email="[email protected]", password="password")
user = authenticate( username="whatever",password="password")

Upvotes: 5

Related Questions