Логотип

Как перейти с Auth0 на Ory

Как перейти с Auth0 на Ory

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

Но по мере роста приложений многие команды начинают искать альтернативы, которые предполагают более низкие долгосрочные затраты, возможность самостоятельного хостинга, использование компонентов с открытым исходным кодом и больший контроль над пользовательскими данными.

Именно здесь на помощь приходит Ory.

Ory предоставляет современный стек управления идентификацией и доступом, основанный на открытых стандартах, таких как OAuth 2.0, OpenID Connect и WebAuthn. Вы можете использовать его через Ory Network (управляемый SaaS) или развернуть самостоятельно в своей инфраструктуре.

В этом руководстве мы расскажем о пошаговой миграции с Auth0 на Ory, включая экспорт данных пользователей, замену SDK и подводные камни, о которых вам никто не расскажет.

 

Миграция с Auth0 на Ory: обзор

Миграция с Auth0 на Ory состоит из 5 этапов:

  1. Экспортируйте учетные записи пользователей из Auth0 с помощью API управления
  2. Запросите хеши паролей через службу поддержки Auth0 (только для платных тарифных планов)
  3. Настройте проект Ory (в сети Ory или на собственном хостинге)
  4. Импортируйте идентификационные данные пользователей с помощью API администратора Ory
  5. Замените SDK Auth0 в своем приложении на SDK Ory

 

Auth0 против Ory: сравнение

Прежде чем переходить на новую платформу, узнайте, чем вы торгуете.

ОсобенностьAuth0Ory
Скорость настройки✅ Очень быстрый⚠️ Более крутая кривая
Управляемое облако✅ Да✅ Да (Ory Network)
Возможность самостоятельного размещения❌ Нет✅ Да
Открытый исходный код❌ Нет✅ Да
Владение пользовательским интерфейсом⚠️ Настраиваемый, но ограниченный✅ Полностью автономный
OAuth2/OIDC
Вход в социальную сеть
МИД
Ценообразование в масштабе❌ Дорогие✅ Значительно дешевле
Блокировка поставщика❌ Высокая✅ Низкое
Владение данными❌ Auth0 хранит ваши данные✅ Он принадлежит тебе

 

Когда стоит остаться на Auth0: у вас небольшая команда, скорость важнее стоимости, вам не нужен собственный хостинг, и вы готовы платить за удобство.

Когда стоит перейти на Ory: у вас более 10 000 активных пользователей в месяц, вы хотите получить полный контроль над пользовательскими данными, разместить приложение на собственном хостинге (для соблюдения нормативных требований, «воздушного зазора» и GDPR) или у вас возникли проблемы с оплатой услуг Auth0.

Хотите получить полную информацию о функциях? У Ory есть официальное сравнение, в котором указаны уровни цен, поддержка протоколов, варианты развертывания, функции обеспечения соответствия требованиям и доступность SDK:

 

Прочтите это в первую очередь, если вы все еще сомневаетесь, стоит ли вам переходить на новый язык. В этой статье мы исходим из того, что вы уже приняли решение.

 

Стоимость

Цены на Ory Network:

  • Бесплатно: Разработка/тестирование
  • Рост: Цена за активного пользователя, прошедшего аутентификацию в течение дня (aDAU), обычно в 5–10 раз ниже, чем у Auth0 при масштабировании
  • Самостоятельное размещение (корпоративная лицензия): Фиксированная плата, неограниченное количество пользователей

 

Цены на Auth0 часто меняются. Пожалуйста, ознакомьтесь с актуальными тарифами на auth0.com/pricing, прежде чем принимать какие-либо решения.

Читать  Pangolin 1.16 получил SSH-daemon аутентификации и улучшения интерфейса

 

Стратегия миграции

У вас есть два варианта:

Вариант А: Ory Network (управляемое облако): лучший вариант, если вы хотите, чтобы за вас все делали, но при этом избежать привязки к тарифному плану и сервису Auth0. Минимальные затраты на инфраструктуру. Изменения в коде сводятся в основном к замене SDK.

Вариант Б: Ory на собственном хостинге (Kratos + Hydra): лучший вариант, если вам нужен полный суверенитет данных, изолированная среда или соблюдение нормативных требований. Требуется больше времени на настройку, но все будет в вашем распоряжении.

 

Шаг 1. Экспорт пользователей Auth0

Auth0 позволяет экспортировать пользователей через API управления. Вам понадобится токен API управления.

# Получить токен API управления (замените YOUR_DOMAIN и учетные данные)
curl --request POST \
  --url https://YOUR_DOMAIN.auth0.com/oauth/token \
  --header 'content-type: application/json' \
  --data '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://YOUR_DOMAIN.auth0.com/api/v2/",
    "grant_type": "client_credentials"
  }'

 

Затем экспортируйте пользователей:

curl --request POST \
  --url 'https://YOUR_DOMAIN.auth0.com/api/v2/jobs/users-exports' \
  --header 'authorization: Bearer YOUR_MGMT_TOKEN' \
  --header 'content-type: application/json' \
  --data '{
    "connection_id": "YOUR_CONNECTION_ID",
    "format": "json",
    "fields": [
      {"name": "user_id"},
      {"name": "email"},
      {"name": "name"},
      {"name": "email_verified"},
      {"name": "created_at"}
    ]
  }'

 

Проверяйте статус задания до его завершения:

curl --request GET \
  --url 'https://YOUR_DOMAIN.auth0.com/api/v2/jobs/YOUR_JOB_ID' \
  --header 'authorization: Bearer YOUR_MGMT_TOKEN'

Ситуация с хешированием паролей (прочитайте внимательно)

Auth0 не включает хешированные пароли в стандартный пакетный экспорт. Однако есть два возможных решения:

Вариант А — запросить хешированные пароли (только для платных планов Auth0):

Платные клиенты Auth0 могут запросить экспорт хэшей паролей, отправив запрос в службу поддержки: Панель управления Auth0 → Поддержка → Запросы → Посмотреть все → Отправить запрос → «У меня вопрос по поводу моей учетной записи Auth0» → «Я хотел бы получить экспорт хэшей паролей моего клиента».

После обработки запроса Auth0 вы получите сжатый JSON-файл с идентификаторами пользователей, хешированными паролями и сопутствующей информацией. Импортируйте их с помощью поля credentials.password.config.hashed_password в Ory (см. шаг 3).

Путь Б — плавная миграция (все планы):

Импортируйте учетные записи пользователей без паролей, а затем используйте крюк для миграции паролей от Ory, чтобы при следующем входе в систему пользователи могли лениво выполнить миграцию. Они еще раз проходят аутентификацию в Auth0, после чего Ory берет все на себя.

Пользователи бесплатного уровня Auth0 не могут экспортировать хэши и должны использовать путь B.

 

Шаг 2. Настройка Ory

Вариант A: сеть Ory

# Установите Ory CLI — Linux/macOS с помощью официального установочного скрипта:
curl https://raw.githubusercontent.com/ory/meta/master/install.sh | sh -s ory
sudo mv ./ory /usr/local/bin/

# Пользователи macOS могут воспользоваться Homebrew:
# brew install ory/tap/cli

# Войдите в систему или создайте учетную запись
ory auth

# Создайте новый проект
ory create project --name "my-app"

# Получите идентификаторы своего рабочего пространства и проекта (необходимы для команд настройки)
ory list workspaces
ory list projects --workspace <workspace-id>

 

URL вашего SDK будет выглядеть так: https://yourproject.projects.oryapis.com

 

Вариант Б: собственный хостинг

Примечание по версии: перед развертыванием всегда проверяйте последнюю стабильную версию образа по тегу changelog.ory.com. Для тестирования можно использовать latestв рабочей среде закрепите образ за конкретным проверенным тегом.

Для продакшена лучше использовать PostgreSQL, а не SQLite:

# docker-compose.yml (выдержка из рабочей версии)
services:
 postgres:
 image: postgres:15
 environment:
 POSTGRES_USER: kratos
 POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # используйте .env, никогда не прописывайте пароль вручную
 POSTGRES_DB: kratos
 volumes:
 - pgdata:/var/lib/postgresql/data

 kratos:
 image: oryd/kratos:latest # замените на текущий закрепленный тег из changelog.ory.com
 environment:
 - DSN=postgres://kratos:${POSTGRES_PASSWORD}@postgres:5432/kratos?sslmode=disable

volumes:
  pgdata:

Шаг 3. Импорт пользователей в Ory

Административный API Ory Kratos поддерживает как создание отдельных идентификаторов (POST /admin/identities), так и настоящий массовый импорт (PATCH /admin/identities). Для масштабных миграций используйте пакетную конечную точку. Она позволяет отправлять несколько идентификаторов в одном запросе, корректно обрабатывает частичные сбои и возвращает результаты по каждому идентификатору, сопоставленные с patch_id.

Примечание по идентификатору схемы: в новых проектах Ory Network "preset://email" используется по умолчанию schema_id. В проектах, размещенных на собственных серверах, может использоваться другое значение. Проверьте default_schema_id в конфигурации Ory Identity. Схема preset://email допускает использование email только в качестве признака (additionalProperties: false), поэтому данные имени хранятся в metadata_public ниже. Если в вашей схеме есть поля с именами, вы можете перенести их в traits напрямую.

 

// import-users.js
const axios = require('axios');
const fs = require('fs');
const { randomUUID } = require('crypto'); // Node.js 14.17+

const KRATOS_ADMIN = process.env.KRATOS_ADMIN_URL || 'http://localhost:4434';
const ORY_API_KEY = process.env.ORY_API_KEY || '';

// Ory Network по умолчанию: "preset://email"
// При самостоятельном размещении: соответствует настроенному вами default_schema_id (например, "default")
const SCHEMA_ID = process.env.ORY_SCHEMA_ID || 'preset://email';

const auth0Users = JSON.parse(fs.readFileSync('./auth0-export.json', 'utf8'));

function buildIdentityPatch(auth0User) {
 return {
 patch_id: randomUUID(), // сопоставляет каждую запись в ответе с исходными данными
 create: {
 schema_id: SCHEMA_ID,
 state: 'active',
 traits: {
 email: auth0User.email,
 // Примечание: в предустановке preset://email параметр additionalProperties имеет значение false — допускается только email.
 // Если в вашей схеме есть поля с именами, добавьте их сюда:
 // name: { first: auth0User.name?.split(' ')[0], last: auth0User.name?.split(' ').slice(1).join(' ') }
 },
 verifiable_addresses: [
 {
 value: auth0User.email,
 verified: auth0User.email_verified,
 via: 'email',
 status: auth0User.email_verified ? 'завершено' : 'ожидает',
 },
 ],
 // Сохраняем идентификатор Auth0 и отображаемое имя для справки при переходе
 metadata_public: {
 auth0_id: auth0User.user_id,
 name: auth0User.name || '',
 migrated_at: new Date().toISOString(),
 },
 },
 };
}

async function importBatch(patches) {
 const headers = { 'Content-Type': 'application/json' };
 if (ORY_API_KEY) headers['Authorization'] = `Bearer ${ORY_API_KEY}`;

 const { data } = await axios.patch(
 `${KRATOS_ADMIN}/admin/identities`,
 { identities: patches },
 { headers }
 );
 return data.identities; // [{ action, patch_id, identity (строка UUID) | error }]
}

async function importAll() {
 const batchSize = 50; // уменьшите до 20–25, если столкнетесь с таймаутами 504
 const results = [];

 for (let i = 0; i < auth0Users.length; i += batchSize) {
 const batch = auth0Users.slice(i, i + batchSize);
 const patches = batch.map(buildIdentityPatch);

 // Сопоставляем patch_id → email, чтобы можно было сопоставить результаты с исходными данными пользователя
 const patchIdToEmail = new Map(patches.map((p, idx) => [p.patch_id, batch[idx].email]));

 try {
 const batchResults = await importBatch(patches);
 for (const r of batchResults) {
 const email = patchIdToEmail.get(r.patch_id) || r.patch_id;
 if (r.action === 'create') {
 console.log(`✅ Импортировано: ${email} → Ory ID: ${r.identity}`);
 results.push({ success: true, email, oryId: r.identity });
 } else {
 const reason = r.error?.reason || r.error?.message || 'неизвестная ошибка';
 console.error(`❌ Ошибка: ${email} — ${reason}`);
 results.push({ success: false, email, error: r.error });
 }
 }
 } catch (err) {
 console.error(`❌ Ошибка в пакете ${i}–${i + batchSize}:`, err.response?.data || err.message);
 }

 await new Promise(r => setTimeout(r, 200)); // короткая пауза между пакетами
 }

 const succeeded = results.filter(r => r.success).length;
 const failed = results.filter(r => !r.success).length;
 console.log(`\nИмпорт завершен: ${succeeded} выполнено успешно, ${failed} не выполнено`);
 fs.writeFileSync('./import-results.json', JSON.stringify(results, null, 2));
}

importAll();

 

Читать  Контроль доступа: идентификация, аутентификация и авторизация

Запустите его:

KRATOS_ADMIN_URL=https://yourproject.projects.oryapis.com \
ORY_API_KEY=ваш-api-ключ-ory \
node import-users.js

 

Если у вас есть хэши паролей от Auth0: добавьте блок credentials внутрь каждого объекта create:

"credentials": {
 "password": {
 "config": {
 "hashed_password": "$2a$10$..."
 }
 }
}

 

Ory поддерживает алгоритмы BCrypt, Argon2, MD5, SHA, PBKDF2, SCrypt и другие — для большинства экспортируемых данных Auth0 повторное хеширование не требуется.

 

Шаг 4. Замените SDK в своем приложении

SDK Auth0 (ранее):

const { auth, requiresAuth } = require('express-openid-connect');

app.use(auth({
 authRequired: false,
 auth0Logout: true,
 secret: process.env.AUTH0_SECRET,
 baseURL: 'http://localhost:3000',
 clientID: process.env.AUTH0_CLIENT_ID,
 issuerBaseURL: `https://${process.env.AUTH0_DOMAIN}`,
}));

app.get('/profile', requiresAuth(), (req, res) => {
 res.json(req.oidc.user);
});

Ory SDK (после):

const { FrontendApi, Configuration } = require('@ory/client-fetch');

const ory = new FrontendApi(new Configuration({
 basePath: process.env.ORY_SDK_URL,
 credentials: 'include',
}));

const requireAuth = async (req, res, next) => {
 try {
 const session = await ory.toSession({ cookie: req.headers.cookie });
 req.user = session.identity;
 next();
 } catch {
 res.redirect('/login');
 }
};

app.get('/profile', requireAuth, (req, res) => {
 res.json(req.user.traits);
});

Изменения переменных среды:

# Удалить:
AUTH0_SECRET=...
AUTH0_CLIENT_ID=...
AUTH0_DOMAIN=...

# Добавьте:
ORY_SDK_URL=https://yourproject.projects.oryapis.com

Шаг 5. Перенос социальных связей

Вариант А: Ory Network

В Ory Network социальные сервисы настраиваются через пользовательский интерфейс Ory Console или Ory CLI, а не путем прямого редактирования конфигурационных файлов.

Через консоль (проще всего для таких популярных сервисов, как Google и GitHub):

  1. Перейдите в свой проект на console.ory.sh
  2. Перейдите в раздел Аутентификация → Вход через социальные сети (OIDC)
  3. Включите переключатель Включить OpenID Connect и укажите базовый URI перенаправления
  4. Нажмите Добавить нового поставщика OpenID Connect, выберите поставщика и введите идентификатор клиента и секретный ключ из консоли разработчика поставщика
Читать  Как скопировать ключи SSH

С помощью интерфейса командной строки Ory (с возможностью написания скриптов, подходит для автоматизации):

# Получите текущую конфигурацию идентификатора для вашего проекта
ory get identity-config \
  --project <project-id> \
  --workspace <workspace-id> \
  --format yaml > identity-config.yaml

 

В разделе identity-config.yaml добавьте своих провайдеров в methods.oidc:

methods:
  oidc:
    config:
      base_redirect_uri: https://your-app.example.com  # базовый URL-адрес вашего приложения, А НЕ URL-адрес проекта Ory
      providers:
        - id: google              # используется в URL обратного вызова OAuth — не изменяется после первого входа в систему
          provider: google
          label: Google
          client_id: YOUR_GOOGLE_CLIENT_ID
          client_secret: YOUR_GOOGLE_CLIENT_SECRET
          scope:
            - email
            - profile
          mapper_url: base64://YOUR_BASE64_ENCODED_JSONNET
          enabled: true

        - id: github              # используется в URL обратного вызова OAuth — не изменяется после первого входа в систему
          provider: github
          label: GitHub
          client_id: YOUR_GITHUB_CLIENT_ID
          client_secret: YOUR_GITHUB_CLIENT_SECRET
          scope:
            - user:email
          mapper_url: base64://YOUR_BASE64_ENCODED_JSONNET
          enabled: true

 

Затем примените изменения:

ory update identity-config \
  --project <project-id> \
  --workspace <workspace-id> \
  --file identity-config.yaml

 

Вариант Б: собственный хостинг

Для Kratos с собственным хостингом добавьте провайдеров напрямую в kratos/config.yml в разделе selfservice.methods.oidc:

selfservice:
 methods:
 oidc:
 enabled: true
 config:
 providers:
 - id: google
 provider: google
 client_id: YOUR_GOOGLE_CLIENT_ID
 client_secret: YOUR_GOOGLE_CLIENT_SECRET
 scope:
 - email
 - profile
 mapper_url: base64://YOUR_JSONNET_MAPPER

 - id: github
 provider: github
 client_id: ВАШ_ИДЕНТИФИКАТОР_КЛИЕНТА_GITHUB
 client_secret: ВАШ_СЕКРЕТНЫЙ_КЛЮЧ_КЛИЕНТА_GITHUB
 scope:
 - user:email
 mapper_url: base64://YOUR_JSONNET_MAPPER

 

Пользователи Auth0 из социальных сетей будут по-прежнему использовать функцию «Войти через Google/GitHub». Ory создает новые учетные записи при первом входе. Сопоставьте адрес электронной почты с существующими учетными записями.

 

5 подводных камней, о которых вам никто не расскажет

1. Проблема с хешированием паролей: см. шаг 1 выше. Продумайте плавный переход или запросите хеширование через службу поддержки.

2. Различия в форматах токенов: Auth0 использует JWT с пользовательскими утверждениями. Ory Hydra выдает токены OAuth2, соответствующие стандартам. Если ваш API проверяет токены напрямую, обновите логику проверки.

3. У правил и действий Auth0 нет прямого эквивалента: действия Auth0 после входа в систему (пользовательский JavaScript) сопоставляются с действиями Ory. Перед миграцией задокументируйте каждое действие и создайте эквивалентные обработчики действий Ory.

4. Утверждение sub изменится: уникальный идентификатор каждого пользователя в Ory будет представлять собой новый UUID. Если вы храните идентификаторы пользователей Auth0 в своей базе данных, при переходе на новую систему вам понадобится таблица сопоставления. Поле metadata_public.auth0_id, заданное при импорте, станет вашим связующим звеном.

5. В Ory более строгие требования к CORS: в Ory требуется явная настройка разрешенных источников. Убедитесь, что serve.public.cors.allowed_origins в вашей конфигурации Kratos точно соответствует домену вашего приложения.

 

Поэтапный план миграции (внедрение без простоев)

  1. Импортируйте пользователей в Ory, не касаясь вашего live-приложения
  2. Запускайте оба приложения параллельно — новые регистрации отправляются в Ory, существующие пользователи по-прежнему используют Auth0
  3. Ленивая миграция существующих пользователей с помощью сброса пароля или подключения к миграции при следующем входе в систему
  4. Переключите свое приложение на Ory SDK, как только будет перенесено > 90% активных пользователей
  5. Поддерживайте активность клиента Auth0 в течение 30-60 дней после отключения в качестве подстраховки
  6. Отключите Auth0, как только будете уверены

 

Окончательный Вердикт

Переход с Auth0 на Ory — задача не из простых. Для производственного приложения потребуется 1–2 спринта. Но результат того стоит: меньшие затраты при масштабировании, полное владение данными и возможность самостоятельного хостинга, если это когда-нибудь понадобится.

Ресурсы:

Редактор: AndreyEx

Рейтинг: 5 (1 голос)

Важно: Данная статья носит информационный характер. Автор не несёт ответственности за возможные сбои или ошибки, возникшие при использовании описанного программного обеспечения.

Если статья понравилась, то поделитесь ей в социальных сетях:

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

шестнадцать − один =

Это может быть вам интересно


Спасибо!

Теперь редакторы в курсе.

Прокрутить страницу до начала