Реализация переноса пользователей и паролей при миграции сайта

Перенос пользователей — технический квест, который мы решаем без потери доступа

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Реализация переноса пользователей и паролей при миграции сайта
Сложный
~2-3 дня

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    980
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1240
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

Перенос пользователей — технический квест, который мы решаем без потери доступа

Отметим: когда бизнес решает переехать на новую CMS или фреймворк, самый деликатный вопрос — пользователи. Их пароли зашифрованы старым алгоритмом — sha512 с солью (Drupal 7), phpass (WordPress) или md5($password.$salt) из самописной CRM. Новая система эти хэши не понимает, и просто скопировать базу нельзя — никто не войдёт. Более того, инженеры часто допускают ошибку: копируют таблицу пользователей как есть, а потом выясняют, что все пароли недействительны. Результат — массовый сброс сессий и потеря лояльности. Мы провели более 50 миграций, включая проекты с 200 000 пользователей, и знаем, как провести перенос так, чтобы пользователи даже не заметили переезда. Ниже — проверенная стратегия и инструменты (Python, Golang, Laravel, Django), которые мы используем в каждом проекте. Мы гарантируем, что ни один пользователь не потеряет доступ.

Какие проблемы решаем?

  • Несовместимость алгоритмов хэширования: старая система использует sha512 или MD5, новая — только bcrypt.
  • Дубликаты пользователей по email при объединении баз.
  • Потеря ролей и прав доступа при переносе.
  • Необходимость сохранить активные сессии и избежать массового перелогина.
  • SSO-интеграция для временной совместной работы старой и новой платформ.

Почему lazy migration лучше полного рехэширования?

Lazy migration позволяет перенести пользователей без простоя и потери доступа. Старые хэши остаются в базе, а при каждом входе проверяется алгоритм и при успехе пароль перехэшируется новым. Это в 3–5 раз быстрее полного принудительного сброса и не вызывает отток аудитории. Кроме того, он позволяет постепенно переносить пользователей без простоя — можно мигрировать базу в фоне, а 100% нагрузка на старую систему сохраняется.

Стратегия Время реализации Влияние на пользователей Безопасность
Lazy migration 1-2 дня Минимальное, процесс прозрачен Высокая при правильной реализации
Принудительный сброс 1-3 дня Требует от пользователя смены пароля Высокая
Полное рехэширование 3-7 дней Среднее, возможна временная недоступность Средняя (ошибки при массовом перехэшировании)

Принудительный сброс для legacy алгоритмов

Если поддержка устаревших алгоритмов (MD5, SHA1) нежелательна, мы отправляем пользователям email с токеном для сброса. Это безопаснее, чем хранить ненадёжные хэши. Сценарий: скрипт находит всех пользователей с алгоритмом legacy_md5, генерирует одноразовый токен и отправляет письмо. Срок действия токена — 7 дней. После успешной смены пароль сохраняется уже с bcrypt.

Что делать, если алгоритм не поддерживается новой системой?

В этом случае мы внедряем промежуточный слой верификации. Например, для phpass (WordPress) используем собственную реализацию на Python. «PHPass is a portable public domain password hashing framework» — его алгоритм поддерживается через кастомную функцию. Аналогично для PBKDF2 (Django) и sha512 (Drupal 7). Это позволяет сохранить совместимость без переписывания всей системы.

Как реализовать lazy migration?

Пошаговый план:

  1. Проанализируйте существующие хэши и определите алгоритмы.
  2. Реализуйте функцию верификации для каждого алгоритма.
  3. Добавьте логику перехэширования при успешном входе.
  4. Разработайте ETL-скрипт для переноса данных.
  5. Протестируйте на копии базы.
  6. Запустите миграцию и мониторьте ошибки.

Основная идея — хранить исходный хэш и метку алгоритма в поле password_algorithm. При входе вызываем функцию verify_password, которая проверяет алгоритм, и при успехе — upgrade_password_hash. Рассмотрим реализацию на Python.

# models/user.py class User(BaseModel): password_hash: str password_algorithm: str # 'bcrypt', 'phpass', 'sha512', 'legacy_md5' def verify_password(self, plain_password: str) -> bool: if self.password_algorithm == 'bcrypt': return bcrypt.checkpw(plain_password.encode(), self.password_hash.encode()) elif self.password_algorithm == 'phpass': return phpass_check(plain_password, self.password_hash) elif self.password_algorithm == 'legacy_md5': return hashlib.md5(plain_password.encode()).hexdigest() == self.password_hash elif self.password_algorithm == 'pbkdf2_sha256': return django_pbkdf2_check(plain_password, self.password_hash) return False def upgrade_password_hash(self, plain_password: str): new_hash = bcrypt.hashpw(plain_password.encode(), bcrypt.gensalt(rounds=12)) self.password_hash = new_hash.decode() self.password_algorithm = 'bcrypt' db.save(self) 

Проверка совместимости phpass (WordPress)

Детали реализации для WordPress WordPress использует [phpass](https://en.wikipedia.org/wiki/PHPass). Для интеграции с Python:
import hashlib ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' def phpass_check(password: str, stored_hash: str) -> bool: if stored_hash.startswith('$P$') or stored_hash.startswith('$H$'): return _phpass_verify(password, stored_hash) return hashlib.md5(password.encode()).hexdigest() == stored_hash def _phpass_verify(password: str, hash_str: str) -> bool: count_log2 = ITOA64.index(hash_str[3]) count = 1 << count_log2 salt = hash_str[4:12] hash_val = hashlib.md5((salt + password).encode()).digest() for _ in range(count): hash_val = hashlib.md5(hash_val + password.encode()).digest() output = _encode64(hash_val, 16) return hash_str[12:34] == output[:22] 

ETL: перенос пользователей с маппингом ролей

Для массового переноса используем ETL-скрипт. Пример для WordPress:

def migrate_users_from_wordpress(wp_db, new_db): cursor = wp_db.cursor(dictionary=True) cursor.execute(""" SELECT u.ID, u.user_login, u.user_pass, u.user_email, u.user_registered, u.display_name, um.meta_value as first_name, um2.meta_value as last_name FROM wp_users u LEFT JOIN wp_usermeta um ON u.ID = um.user_id AND um.meta_key = 'first_name' LEFT JOIN wp_usermeta um2 ON u.ID = um2.user_id AND um2.meta_key = 'last_name' ORDER BY u.ID """) migrated = 0 skipped = 0 for wp_user in cursor.fetchall(): existing = new_db.get_user_by_email(wp_user['user_email']) if existing: skipped += 1 continue algorithm = detect_wp_hash_algorithm(wp_user['user_pass']) new_db.create_user({ 'username': wp_user['user_login'], 'email': wp_user['user_email'], 'password_hash': wp_user['user_pass'], 'password_algorithm': algorithm, 'display_name': wp_user['display_name'], 'created_at': wp_user['user_registered'], 'legacy_id': wp_user['ID'], }) # Маппинг ролей: из wp_usermeta meta_key = 'wp_capabilities' roles = get_user_roles(wp_db, wp_user['ID']) new_db.assign_roles(wp_user['user_email'], roles) migrated += 1 print(f"Migrated: {migrated}, Skipped: {skipped}") 

Обработка входа и перехэширование

def login(email: str, password: str): user = db.get_user_by_email(email) if not user: return None if user.verify_password(password): if user.password_algorithm != 'bcrypt': user.upgrade_password_hash(password) return create_session(user) return None 

Что входит в работу по миграции пользователей?

  • Аудит текущей базы пользователей и алгоритмов хэширования.
  • Разработка скриптов ETL с учётом маппинга ролей и дополнительных полей.
  • Реализация lazy migration (или принудительного сброса) с тестированием на копии.
  • Настройка мониторинга ошибок после деплоя (24-часовое наблюдение).
  • Документация по процедуре отката и резервное копирование.

Сроки выполнения и типичные ошибки

Ориентировочные сроки

  • Для базы до 100 000 пользователей: 2–3 рабочих дня на аудит, разработку и тестирование.
  • Для базы от 100 000 до 500 000: 5–7 дней с учётом ETL и нагрузочного тестирования.
  • В крупных проектах с десятками ролей и кастомными полями срок может быть увеличен.

Типичные ошибки при миграции

  • Пропуск проверки дубликатов по email — приводит к конфликтам и потере данных.
  • Игнорирование маппинга ролей — пользователь переносится, но теряет права доступа.
  • Попытка рехэшировать все пароли сразу — вызывает CPU-нагрузку и ошибки.
  • Отсутствие плана отката — при неудаче нет быстрого восстановления.
  • Незакрытие старых сессий — пользователи остаются в системе под старыми данными.

Советы:

  • Всегда тестируйте на копии базы.
  • Используйте транзакции и скрипты с rollback.
  • Настройте мониторинг ошибок после деплоя (первые 24 часа критичны).
  • Храните резервную копию старой базы и скрипт обратной миграции.

Сравнение алгоритмов хэширования

Алгоритм Длина хэша Устойчивость к брутфорсу Стандарт в CMS
bcrypt 60 символов Высокая (cost adjustable) Laravel, Symfony, Rails
phpass 34 символа Средняя (MD5-based) WordPress, Drupal 7
PBKDF2 98 символов Высокая Django, Python
MD5 32 символа Низкая Устаревшие системы

Закажите аудит вашего проекта — первый день бесплатно. Свяжитесь с нами для консультации и получите точную смету с гарантией результата.