Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why user password is not being hashed in django admin?

I created a user when using syncdb command and it logs in perfectly. But when I create a user from django admin, it is created successfully but causes error when logging it in. I get error:

Unknown password hashing algorithm 'password'. Did you specify it in the PASSWORD_HASHERS setting?

What's the issue? how can I resolve it so the password is automatically encrypted when saving the user in admin?

like image 659
wasimbhalli Avatar asked Sep 14 '12 10:09

wasimbhalli


4 Answers

Solution for password being stored as text rather than hashed password is to use UserAdmin from django.contrib.auth.admin instead of ModelAdmin.

from django.contrib.auth.admin import UserAdmin

class EmployeeAdmin(UserAdmin):
    pass

admin.site.register(Employee, EmployeeAdmin)
like image 170
Dawn T Cherian Avatar answered Sep 29 '22 11:09

Dawn T Cherian


I ran into the same problem in a situation where I had subclassed the Django's User, then created a model admin for it and used the automatically generated Django admin form to create a user.

So I had something like this in my models.py

class Employee(User):
    job = models.CharField(max_length=100)

and this in my admin.py

class EmployeeAdmin(admin.ModelAdmin):
    pass
admin.site.register(Employee, EmployeeAdmin)

Now Django automatically creates a form for adding new employees in the Django admin. But when this form is used to create a user, the password will not get hashed at all. So for some reason, Django creates normal text input field for the password when the model is derived from Django's built-in User. I don't know if you had the same case.

Unfortunately I couldn't find an easy solution to fix this. I also have no idea why Django is not creating the correct form field for the password automatically. However one possibility would be to override the automatic form with a custom form that would include a password widget. See https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides .

like image 28
Rubinous Avatar answered Sep 29 '22 11:09

Rubinous


I experienced the same issue shown in Rubinous answer and might also be your problem.

The problem happened when inheriting my user model from django.contrib.admin.ModelAdmin instead of django.contrib.auth.admin.UserAdmin

By doing this, I was bypassing necesary user functionality

like image 31
AMArostegui Avatar answered Sep 29 '22 12:09

AMArostegui


Django does not store passwords as plain-text. It first hashes them and them stores the hash. So when the user logs in, Django applies the same hash function to the users input and then compares the two hashes - from users input and what is stored in the db.

However to make things more flexible, Django does not store password hashes, well it does but in addition, it also stores the algorithm by which the hash was generated. Imagine this scenario - you use hash function X to generate password hashes, but then you realize that that function is no longer secure for whatever reason and you switch to hashing function Y. That however is a problem because at point, whoever's password hash is stored using function X, they would not be able to login anymore. That is why Django also stores the method by which the has was generated, in addition to the hash value itself. This is where PASSWORD_HASHERS setting comes in. The fact that Django stores the method by which the hash is generated in the db, when reading the value, it does not really tell Django as to how to execute the hash function itself. So PASSWORD_HASHERS is sort of like a mapper between the hashing Python function (actually a class but anyway...) and the value stored in the db.

So back to your question. The error message means that Django is not aware of the hashing function password which was used to store the hash of the password in your database, or at least its not in the PASSWORD_HASHERS.

I can think of couple of reasons why that might happen.

  • Make sure that then you do syncdb, it uses the same settings.py file as when you are running the server to access the admin. It might be the case that different settings are used.

  • However developers usually do not modify PASSWORD_HASHERS in the settings.py and just use the default value. In that case, make sure you are using the same Python with the same installed version of Django when you do syncdb and when you run the server. If you do syncdb in one virtualenv, for example, and run server in different env, then Django versions might be different, hence they might have different settings for PASSWORD_HASHERS and therefore where you run syncdb, it might be using a hashing function which is not defined when you run the server.

like image 29
miki725 Avatar answered Sep 29 '22 12:09

miki725