Перенос поля пароля в Django - PullRequest
6 голосов
/ 19 ноября 2011

Я использовал Django раньше (версия 1.2), и в целом он мне нравится ... он особенно хорош для быстрого запуска и запуска нового проекта. Но, в этом случае, я переписываю существующую систему и перевожу ее на Python / Django. Итак, у меня уже есть база данных MySQL, в которой есть таблица «users» ... эта таблица хранит пароль пользователя с функцией MySQL SHA1 (без соли и т. Д.).

В рамках миграции я собираюсь исправить некоторые недостатки моделирования данных и портировать их на PostgreSQL.

Я бы очень хотел использовать django.contrib.auth, но мне неясно, что мне нужно делать. Я прочитал документацию и знаю, что могу отделить необходимую информацию о пользователе и «дополнительную» информацию, которую имею, и поместить ее в UserProfile.

Но как обращаться с паролями, хранящимися в базе данных MySQL?

Кто-нибудь занимался этим раньше? Какой подход вы выбрали?

Ответы [ 3 ]

8 голосов
/ 13 января 2012

Вот что я сделал, чтобы все заработало. Я создал пользовательский бэкэнд аутентификации. Примечание: я использую адрес электронной почты в качестве имени пользователя.

Вот мой код:

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

Затем я добавил следующее в settings.py:

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

Похоже, предложение @Dougal предназначено для следующего выпуска Django и не было доступно для меня (я использую 1.3.1). Однако, похоже, что это будет лучшее решение.

1 голос
/ 24 февраля 2015

Последние версии Django предоставляют хэш для несоленных устаревших паролей. Просто добавьте это в ваш файл настроек:

PASSWORD_HASHERS = (
  ...
  'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher',
)
1 голос
/ 19 ноября 2011

Вы, вероятно, можете поместить его прямо в поле user_password - см. документы Django .Поскольку у вас нет соли, попробуйте использовать формат sha1$$password_hash.Я не исследовал, чтобы увидеть, что он будет работать с чистой солью, но это, вероятно, единственный способ, которым вы сможете перенести его без взлома django.contrib.auth или написания собственного бэкэнда аутентификации.

В противном случае, вы могли бы просто установить непригодный пароль (каноническое, что нужно сделать, это установить поле в !) для пользователей и указать им систему забытых паролей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...