Migrating a password field to Django
Here is what I did to get things working. I created a custom authentication backend. Note: I'm using the email address as the username.
Here is my code:
from django.db.models import get_modelfrom django.contrib.auth.models import Userfrom hashlib import sha1class MyUserAuthBackend(object): def check_legacy_password(self, db_password, supplied_password): return constant_time_compare(sha1(supplied_password).hexdigest(), db_password) def authenticate(self, username=None, password=None): """ Authenticate a user based on email address as the user name. """ try: user = User.objects.get(email=username) if '$' not in user.password: if self.check_legacy_password(user.password, password): user.set_password(password) user.save() return user else: return None else: if user.check_password(password): return user except User.DoesNotExist: return None def get_user(self, user_id): """ Get a User object from the user_id. """ try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None
Then I added the following to settings.py:
AUTHENTICATION_BACKENDS = ( 'my_website.my_app.my_file.MyUserAuthBackend',)
The suggestion from @Dougal appears to be for the next release of Django and was not available for me (I'm using 1.3.1). However, it seems like it will be a better solution.
You can probably put it straight into the user_password
field - see the Django docs. Since you don't have a salt, try using the format sha1$$password_hash
. I haven't investigated to see that it'll work with a blank salt, but that's probably the only way you're going to be able to migrate it without hacking django.contrib.auth
or writing your own authentication backend.
Otherwise, you could just set an unusable password (the canonical thing to do is set the field to !
) for users and point them to the forgot-password system.
Recent versions of Django provide a hasher for unsalted legacy passwords. Just add this to your settings file:
PASSWORD_HASHERS = ( ... 'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher',)