Reputation: 3178
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
Reputation: 1
I faced similar issue. After setting the user status to Active worked for me in my custom user account table.
Upvotes: 0
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
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:
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
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
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
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
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
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
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
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
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
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