Интернационализированные email‑адреса могут не пройти при регистрации из‑за IDN, нормализации Unicode и пробелов в поддержке SMTPUTF8. Узнайте безопасные шаги валидации.

Регулярное выражение может оценить только форму текста, но не скажет, сможет ли домен принять почту или сможет ли ваш стек доставки доставить сообщение. Regex‑шаблоны часто либо слишком строгие (блокируют корректные интернационализированные домены), либо слишком мягкие (принимают адреса, которые позже отскочат).
Если у вас глобальная аудитория, разрешать Unicode в части домена обычно безопасно: домен можно конвертировать в ASCII для DNS‑проверок. Unicode в локальной части (до @) — более серьёзный выбор: убедитесь, что весь путь доставки поддерживает SMTPUTF8, иначе рискуете получить регистрации, которые не смогут принять верификационные письма или сброс пароля.
Сохраняйте то, что ввёл пользователь, для отображения, но перед DNS или MX‑проверками конвертируйте домен в его ASCII‑форму (punycode). Хранение ASCII‑версии рядом с оригиналом помогает консистентно удалять дубликаты и избегать расхождений между библиотеками, по‑разному работающими с IDN.
Нормализуйте текст на раннем этапе, желательно перед валидацией и сравнением, чтобы визуально одинаковые вводы не создавали разные учётные записи. NFC — практичный выбор: он решает проблему «одинаково смотрящихся, но разных байтов» без чрезмерного изменения символов, которое делает NFKC.
Домены обычно нечувствительны к регистру — их безопасно приводить к нижнему регистру для сравнения и хранения. Локальная часть (до @) технически чувствительна к регистру, и её приведение к нижнему может слить разные адреса на некоторых системах. Поэтому по умолчанию не понижайте регистр локальной части.
Храните оригинал для отображения и каноническую форму для сравнения и уникальности. Каноническая форма обычно: обрезанное внешнее пространство, нормализованное в NFC, домен приведён к нижнему регистру и при необходимости конвертирован в ASCII, тогда как отображаемая форма остаётся удобочитаемой для пользователя.
Сначала проверьте синтаксис, затем убедитесь, что домен разрешается в DNS и проверьте MX‑записи, используя ASCII‑версию домена. Это ловит опечатки и «мертвые» домены, но не доказывает существование конкретного почтового ящика — для этого нужна подтверждающая проверка владения адресом.
Причина обычно не в том, что приложение приняло адрес, а в том, что путь исходящей почты его отвергает. Частая причина — отсутствие поддержки SMTPUTF8 где‑то между вашим приложением, почтовым провайдером и внешними ретрансляторами, что ломает доставку для Unicode‑локальной части, даже если адрес валиден по спецификации.
Обрезайте явные окружные пробелы, но будьте осторожны с «очисткой», которая удаляет невидимые символы: некоторые из них значимы в Unicode. Также полезно обнаруживать и предупреждать о скрытых символах вроде zero‑width‑space, чтобы пользователь мог исправить ввод вместо того, чтобы его тихо отвергли.
Используйте Verimail для замены хрупкой логики проверки на единый API, который валидирует синтаксис в соответствии с RFC, проверяет домен и MX и отмечает рискованные входы вроде disposable‑провайдеров. Это удобно, если вы хотите быстрые и стабильные решения при регистрации без собственной сложной многоступенчатой системы.
Адрес электронной почты может выглядеть нормально и при этом провалиться в тот момент, когда попадает в реальную систему. Главная причина в том, что то, что человек видит как один символ, может храниться разными байтами, по‑разному обрабатываться библиотеками или отклоняться старыми почтовыми серверами.
Типичный пример — søren@exämple.com. Это может быть валидный адрес, но он затрагивает сразу несколько уязвимых точек: Unicode в локальной части, интернационализированный домен и инфраструктуру почты, которая может поддерживать это или нет.
Сбоить может далеко от формы регистрации. Вы принимаете адрес, а затем не можете отправить письмо для сброса пароля, потому что ваш почтовый провайдер (или промежуточный реле) не поддерживает SMTPUTF8. Или ваш regex принимает адрес, а шаг «привести к нижнему регистру и обрезать» превращает его в нечто другое, не то, что ввёл пользователь.
Ложные отказы дорого обходятся, потому что обычно они тихие. Люди бросают регистрацию, повторно вводят другой адрес или открывают тикеты в поддержку, которые трудно воспроизвести. Для глобальной аудитории отказ от интернационализированных адресов может выглядеть как игнорирование их языка.
Ложные допуски стоят по‑другому: некорректные адреса дают bounce‑ы, снижают доставляемость и портят списки. Некоторые правдоподобные вводы сознательно вредоносны: disposable‑домен, ролевые учётные записи для злоупотреблений или спам‑ловушки, которые вредят репутации отправителя.
Цель не в «принимать всё» или «блокировать всё». Цель — принимать реальных пользователей и при этом отсекать очевидно плохие вводы, используя проверки, соответствующие реальной работе почты: отделять представление от хранения, проверять достижимость домена (а не только наличие @) и избегать агрессивных трансформаций, которые тихо переписывают то, что ввёл пользователь.
Адрес состоит из двух частей, разделённых @: локальная часть (до @) и домен (после @). Интернационализированные адреса могут содержать Unicode в любой из частей, и реальная поддержка варьируется в зависимости от того, где именно используется Unicode.
Наиболее распространённый случай — интернационализированный домен (IDN). Пользователь видит домен в своём письме, например maria@bücher.example или li@例子.公司. Под капотом многие системы конвертируют такой домен в ASCII‑форму (часто называемую punycode), чтобы DNS‑запросы и проверки MX работали надёжно.
Сложнее — Unicode в локальной части, например jó[email protected] или ユーザー@domain.com. Это попадает под Email Address Internationalization (EAI) и обычно доставляется через SMTPUTF8. Даже если адрес валиден по современным стандартам, некоторые серверы, старые библиотеки и внешние инструменты могут его отвергнуть. То есть вы можете принять адрес при регистрации, но провалиться при отправке.
Практическая картина поддержки сегодня:
Поэтому обычный yes/no‑regex недостаточен. Regex может отвергнуть легитимных пользователей (например, полностью блокируя не‑ASCII) или принять адреса, до которых вы не сможете доставить почту.
Лучше разделять проверку по сторонам. Для домена нормализуйте и конвертируйте в ASCII для DNS‑проверок. Для локальной части нужно принять политическое решение: вы полностью поддерживаете SMTPUTF8, разрешаете его с предупреждением или блокируете, потому что ваш стек почты не надёжен.
IDN (Internationalized Domain Name) — это домен с не‑ASCII символами, например с акцентами или нелатинскими скриптами. Пользователи видят Unicode‑форму, но DNS построен вокруг ASCII. Это несоответствие — источник многих багов в продакшене.
Чтобы смотреть MX‑записи, проверять домен или даже делать простую DNS‑проверку, обычно нужна ASCII‑форма домена. Конвертация делается по правилам IDNA и даёт punycode, который часто начинается с xn--. Так что пользователь вводит домен, который выглядит нормально, но в логах, базе или у внешнего провайдера вы можете увидеть версию xn--....
Punycode встречается в тех местах, где его стоит ожидать и обрабатывать:
Две распространённые ошибки:
Есть и аспект безопасности. Смешанные скрипты и похожие символы используются для создания доменов, визуально схожих с доверенным брендом. Не стоит блокировать все IDN ради этого, но разумно отмечать их как более рискованные в критичных сценариях: оплата, сброс пароля, админ‑доступ.
Практический подход: принимайте то, что ввёл пользователь, а затем нормализуйте внутри:
Unicode позволяет вводить имена и слова на многих языках, но это также значит, что «один и тот же» символ может кодироваться по‑разному. Если сравнивать строки по сырым байтам или хранить одну форму, а позже получить другую, вы можете получить дубликаты, неудачные логины и сбивающие с толку ошибки «email уже используется».
Простой пример — буква «é». Она может быть одним кодовым пунктом (U+00E9) или двумя: «e» (U+0065) плюс комбинирующий акцент (U+0301). Для человека они выглядят одинаково, но база данных может трактовать их как разные.
Нормализация приводит текст к согласованной форме.
Для обработки email NFC часто является наиболее безопасным выбором для операций «сделать равно».
Правила регистра отличаются между сторонами адреса:
@): безопасно считать нечувствительным к регистру. Приведение к нижнему регистру — стандарт.@): технически чувствительна к регистру, хотя многие провайдеры его игнорируют. Приведение к нижнему может слить два разных адреса на некоторых системах.Практический подход: приводите домен к нижнему регистру и нормализуйте; локальную часть храните так, как ввёл пользователь, одновременно сохраняя каноническую форму для сравнений.
Нормализуйте в тех моментах, где важна согласованность:
Даже с хорошим сервисом валидации ваше приложение должно иметь очевидную политику нормализации и регистра, чтобы легитимных пользователей не блокировали невидимые различия символов.
Большинство багов с интернационализированными адресами появляются на стыках, где одна система делает одно предположение, а следующая — другое. Адрес выглядит нормально для пользователя, но что‑то в цепочке меняет его, отвергает или считает два визуально одинаковых значения разными.
Типичный провал начинается на форме регистрации. Фронтенд‑правила часто допускают только A‑Z, 0‑9 и несколько символов. Мобильные клавиатуры вставляют «умные» знаки препинания, автозаполнение добавляет невидимый пробел в конце. Авто‑понижение регистра тоже может вести себя странно вне базовой ASCII‑области.
На бэкенде маленькие шаги по очистке могут быть разрушительными. Триминг полезен, но удаление «непечатаемых» символов может удалить валидные Unicode‑метки. Ограничения длины — ещё одна тихая проблема: интернационализированные домены при конвертации в punycode «выростают», и вы можете неожиданно упереться в лимит.
Базы данных добавляют свои ловушки. Сопоставления и правила сравнения решают, равны ли две строки. Если одна система хранит композитную форму, а другая позже присылает разложенную, проверки уникальности могут не сработать. Это создаёт дубликаты аккаунтов или блокирует пользователя из‑за несоответствия "уже существует".
Проблемы чаще всего проявляются в:
Исходящая почта — где это становится неизбежно. Если ваш почтовый сервер или промежуточный реле не поддерживает SMTPUTF8, он может отказать в отправке на ящик с не‑ASCII в локальной части. Пользователь регистрируется, но никогда не получает письмо подтверждения.
Реалистичная цепочка отказа выглядит так: пользователь регистрируется с Unicode‑доменом, вы сохраняете его, ваш CRM нормализует иначе, а провайдер почты отказывает при SMTPUTF8. В итоге у вас один пользователь, две несовпадающие строки и письмо, которое не дошло.
Более безопасный workflow начинается с разделения целей: не блокировать реальных людей при регистрации и сохранять формы, с которыми можно сравнивать, отправлять и поддерживать.
Сохраните ввод пользователя. Сохраните адрес ровно так, как введён, затем удалите только очевидные окружные пробелы. Избегайте «полезных» правок: смены регистра, удаления акцентов, удаления точек или плюс‑тегов. Такие изменения могут тихо превратить один адрес в другой.
Сделайте реальную синтаксическую проверку. Оценивайте как «структурно возможен ли этот адрес», а не как «обязательно ли почта дойдёт». Современные правила шире большинства regex, особенно для международных символов.
Примите решение по нормализации и уникальности. Храните сырой адрес плюс каноническую форму (часто NFC) для проверок равенства. Если email — уникальный ключ в системе, зафиксируйте правило, считать ли визуально одинаковые, но по‑разному закодированные вводы за один аккаунт.
Обрабатывайте домен правильно. Нормализуйте и конвертируйте домен в ASCII (punycode) перед любой работой с DNS. Затем проверяйте домен и смотрите MX‑записи (и, при политике, fallback на A/AAAA).
Сформируйте политику для Unicode‑локальной части. Если ваш провайдер исходящей почты не гарантирует доставку по SMTPUTF8, принимайте регистрацию только при наличии плана‑запасного варианта (верификация внутри приложения, альтернативный контакт или явное предупреждение о возможных ограничениях).
Храните небольшие логи исходов валидации, чтобы поддержка могла разбираться с пограничными случаями без догадок.
Часто говорят «валидация email», имея в виду «достанет ли моё сообщение до человека». Это уже доставляемость, и её нельзя полностью доказать при регистрации. С интернационализированными адресами ещё проще спутать «выглядит валидно» и «будет работать везде».
Валидация всё ещё даёт сильные сигналы до сохранения адреса или отправки:
Но валидация не гарантирует, что почтовый ящик существует или примет ваше сообщение. Многие провайдеры блокируют пробу почтовых ящиков, принимают почту для неизвестных пользователей, а затем отдают bounce, или меняют политику без предупреждения.
Более безопасный подход — двухэтапный:
Для «высокого риска» жёсткие блоки часто создают ложноотрицательные срабатывания. Мягкое трение работает лучше: разрешайте регистрацию, требуйте подтверждение перед критичными действиями или запрашивайте дополнительный сигнал только при повышенном риске.
Самый быстрый способ потерять реальных регистраций — считать всё, что вне ASCII, невалидным. Многие легитимные провайдеры поддерживают интернационализированные домены, и часть пользователей действительно ими пользуется.
Много кода в продакшене всё ещё предполагает, что email — это A‑Z, 0‑9, точки и несколько символов. Это ломает IDN‑домены и гарантирует ложные отказы в глобальных продуктах.
Понижение регистра домена допустимо. Понижение регистра локальной части — рискованно.
Нормализация полезна, но делать её бездумно — значит удивлять пользователей. Нормализуйте сознательно, храните оригинал и тестируйте, как downstream‑системы ведут себя.
«Полезные» трансформации, которые подводят:
Бэкенду может потребоваться punycode для проверок DNS, но в UI обычно стоит показывать домен в форме пользователя. Показ xn--... в подтверждениях или ошибках выглядит подозрительно и пугающе, даже если адрес корректен.
Даже если адрес валиден по спецификации, не все почтовые серверы поддерживают SMTPUTF8. Если вы принимаете Unicode‑локальную часть, будьте готовы к различиям в доставляемости у разных провайдеров.
Копирование и вставка вносят неразрывные пробелы, символы с нулевой шириной и лишние пробелы вокруг @. Пользователь не видит эти проблемы, а ваша валидация — видит.
Пример: пользователь вставляет name@пример.рф с завершающим пробелом. Если вы валидируете до триминга, вы отклоните адрес. Если вы пере‑саначите, вы можете изменить локальную часть.
Интернационализированные адреса могут работать end‑to‑end, но только если каждый слой согласен, что он принимает, хранит и отправляет. Перед релизом прогоните проверки, имитирующие поведение продакшена, а не только unit‑тесты.
Убедитесь, что логи и админ‑инструменты корректно отображают удобочитаемую версию без mojibake и что экспорт/импорт не ломает данные. Также проверьте все системы, которые касаются адреса: события аналитики, синхронизация с CRM, вебхуки, CSV‑экспорт и загрузка в хранилище данных. Многие ошибки проявляются при экспорте, а не при вводе.
Конкретный тест: прогоните один и тот же адрес через регистрацию, вход, сброс пароля и потоки слияния аккаунтов. Если он проходит регистрацию, но падает позже, у вас несоответствие в нормализации, хранении или сравнении.
Пользователь регистрируется как marta@bücher.example. На первый взгляд всё нормально, потому что домен в Unicode. Ваша система должна трактовать домен как IDN.
С точки зрения домена: храните удобную для пользователя форму, но для валидации используйте DNS‑безопасную форму. Конвертируйте bücher.example в punycode (xn--bcher-kva.example) перед MX‑запросами. Если вы проверяете только Unicode‑форму, некоторые DNS‑библиотеки могут падать или вести себя непоследовательно.
Теперь тонкая часть: один и тот же email можно ввести несколькими способами, которые визуально идентичны. Допустим, пользователь вводит márta@bücher.example, но «á» может быть одним символом или «a» плюс комбинирующий акцент. Если вы храните только сырой ввод, у пользователя могут появиться две учётные записи, которые выглядят одинаково в UI.
Нормализация решает это. Нормализуйте в NFC перед сравнением, хранением, rate‑limiting и дедупом, и применяйте те же правила везде, где затрагивается адрес.
Локальная часть (до @) — место, где нужна чёткая политика. SMTPUTF8 разрешает Unicode в локальной части, но не все провайдеры поддерживают это полноценно. Практичная политика для многих продуктов:
Если вам нужен единый инструмент для синтаксических проверок, проверки домена и MX, а также фильтра disposable‑провайдеров, API‑сервис проверки email, например Verimail (verimail.co), может дать эти сигналы без хрупких regex.
Дальнейшие шаги, которые защищают вас и при этом не отсекают реальных пользователей: