Password Migration in Django

I used Django before (version 1.2) and generally like it ... it is especially good at quickly starting and starting a new project. But in this case, I rewrite the existing system and port it to Python / Django. So, I already have a MySQL database in which there is a "users" table ... this table stores the user password using the MySQL SHA1 function (without salt, etc.).

As part of the migration, I'm going to fix some of the flaws in data modeling and the port for PostgreSQL.

I would really like to use django.contrib.auth, but I do not understand what I need to do. I have read the documentation and I know that I can separate the required user information and the "additional" information that I have and put it in UserProfile.

But how to handle passwords stored in MySQL db?

Has anyone dealt with this before? What approach did you take?

+6
source share
3 answers

Here is what I did to make it work. I created my own authentication server. Note. I use the email address as the username.

Here is my code:

from django.db.models import get_model from django.contrib.auth.models import User from hashlib import sha1 class 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 settings.py parameters:

 AUTHENTICATION_BACKENDS = ( 'my_website.my_app.my_file.MyUserAuthBackend', ) 

The suggestion from @Dougal is similar to the next release of Django and is not available to me (I use 1.3.1). However, it seems that this will be the best solution.

+8
source

You can probably put it right in the user_password field - see Django docs . Since you don't have salt, try using the sha1$$password_hash format. I have not researched that it will work with empty salt, but this is probably the only way you can transfer it without hacking django.contrib.auth or writing your own backend.

Otherwise, you can simply set an unused password (the canonical task is to set the field for ! ) For users and point them to the system of forgotten passwords.

+1
source

Recent versions of Django provide a hash for unauthorized outdated passwords. Just add this to your settings file:

 PASSWORD_HASHERS = ( ... 'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher', ) 
+1
source

Source: https://habr.com/ru/post/901864/


All Articles