Программист
63,5
рейтинг
4 апреля 2013 в 01:12

Разработка → Прекратите проверять Email с помощью регулярных выражений! перевод

Серьезно, прекратите. Это пустая трата времени и сил. Поищите регулярку для проверки Email в Google, взгляните на нее — и захочется отойти подышать свежим воздухом. Вспоминается одна очень известная цитата:

Некоторые люди, сталкиваясь с проблемой, думают: «О, я воспользуюсь регулярными выражениями».
Теперь у них две проблемы.

Джэйми Завински, regex.info

Вот довольно часто встречающийся пример кода из приложения на Rails, содержащий некоторое подобие системы авторизации:

class User < ActiveRecord::Base
  # Эта регулярка взята из проекта from https://github.com/plataformatec/devise,
  # самой популярной библиотеки авторизации для Rails
  validates_format_of :email, :with => /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/
end

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

class User < ActiveRecord::Base
  validates_format_of :email, :with => /^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6})$/i
end

Или совсем плохо:

class User < ActiveRecord::Base
  validates :email, :with => EmailAddressValidator
end

class EmailValidator < ActiveModel::Validator
  EMAIL_ADDRESS_QTEXT           = Regexp.new '[^\\x0d\\x22\\x5c\\x80-\\xff]', nil, 'n'
  EMAIL_ADDRESS_DTEXT           = Regexp.new '[^\\x0d\\x5b-\\x5d\\x80-\\xff]', nil, 'n'
  EMAIL_ADDRESS_ATOM            = Regexp.new '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+', nil, 'n'
  EMAIL_ADDRESS_QUOTED_PAIR     = Regexp.new '\\x5c[\\x00-\\x7f]', nil, 'n'
  EMAIL_ADDRESS_DOMAIN_LITERAL  = Regexp.new "\\x5b(?:#{EMAIL_ADDRESS_DTEXT}|#{EMAIL_ADDRESS_QUOTED_PAIR})*\\x5d", nil, 'n'
  EMAIL_ADDRESS_QUOTED_STRING   = Regexp.new "\\x22(?:#{EMAIL_ADDRESS_QTEXT}|#{EMAIL_ADDRESS_QUOTED_PAIR})*\\x22", nil, 'n'
  EMAIL_ADDRESS_DOMAIN_REF      = EMAIL_ADDRESS_ATOM
  EMAIL_ADDRESS_SUB_DOMAIN      = "(?:#{EMAIL_ADDRESS_DOMAIN_REF}|#{EMAIL_ADDRESS_DOMAIN_LITERAL})"
  EMAIL_ADDRESS_WORD            = "(?:#{EMAIL_ADDRESS_ATOM}|#{EMAIL_ADDRESS_QUOTED_STRING})"
  EMAIL_ADDRESS_DOMAIN          = "#{EMAIL_ADDRESS_SUB_DOMAIN}(?:\\x2e#{EMAIL_ADDRESS_SUB_DOMAIN})*"
  EMAIL_ADDRESS_LOCAL_PART      = "#{EMAIL_ADDRESS_WORD}(?:\\x2e#{EMAIL_ADDRESS_WORD})*"
  EMAIL_ADDRESS_SPEC            = "#{EMAIL_ADDRESS_LOCAL_PART}\\x40#{EMAIL_ADDRESS_DOMAIN}"
  EMAIL_ADDRESS_PATTERN         = Regexp.new "#{EMAIL_ADDRESS_SPEC}", nil, 'n'
  EMAIL_ADDRESS_EXACT_PATTERN   = Regexp.new "\\A#{EMAIL_ADDRESS_SPEC}\\z", nil, 'n'

  def validate(record)
    unless record.email =~ EMAIL_ADDRESS_EXACT_PATTERN
      record.errors[:email] << 'is invalid'
    end
  end
end

Ага. Неужели действительно нужно использовать нечто настолько сложное? Если перейти по ссылке в начале статьи, вы увидите, что люди уже многие годы пишут (или пытаются написать) регулярки для проверки email-адреса, которые бы соответствовали описанию RFC. Некоторые из них оказываются просто до смешного заумными, как в последнем примере, и все равно не пропускают некоторые корректные адреса.

О том, какой email-адрес является корректным, написано в разделах 3.2.4 и 3.4.1. Там сказано, что при наличии обратного слэша и кавычек остается не так уж много вещей, которые нельзя использовать в адресе. Локальная часть адреса (та строка, что идет перед символом @), может содержать следующие символы:

! $ & * - = ^ ` | ~ # % ' + / ? _ { }

Но знаете что? Вы можете использовать практически любой символ, какой вам заблагорассудится, если заэкранируете его кавычками. Например, вот это — вполне корректный адрес:

"Look at all these spaces!"@ example.com

Прекрасно!

По этой причине, с недавнего времени я проверяю все email-адреса следующим регулярным выражением:

class User < ActiveRecord::Base
  validates_format_of :email, :with => /@/
end

Элементарно, не правда ли? В адресе должен присутствовать символ @. Как правило, этим я и ограничиваюсь. Вкупе с полем для повторного ввода адреса два этих способа позволяют отсеять львиную долю ошибок, связанных со вводом некорректных данных.

Но что, если бы я предложил вам способ проверить email на валидность, в котором вообще не используются регулярные выражения? Он неожиданно прост, и, скорее всего, вы и так его применяете.

Просто пошлите пользователю его письмо!

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

Представьте себе такой сценарий. Я регистрируюсь на вашем сайте под следующим адресом:

qwiufaisjdbvaadsjghb@gmail.com

Да ладно вам! С этой хренью ни один почтовый демон работать не станет, но форматирование в полном порядке: это же валидный email-адрес! Для решения данной проблемы вы пишете систему, которая после регистрации отправляет мне email со ссылкой, по которой я должен перейти. Это требуется для того, чтобы удостовериться, что я действительно имею доступ к почтовому ящику, на который регистрируюсь. В таком случае, зачем проверять формат адресов? Результат отправки письма на неправильный адрес будет точно такой же — письмо не примет сервер. Если пользователь ввел некорректный адрес, он не получит письмо и попытается зарегистрироваться на вашем сайте еще раз, если ему это и правда нужно. Вот и все.

Так что не налегайте на замороченные регулярные выражения. Если вы правда хотите проверять адрес прямо на форме регистрации, добавьте поле для повторного ввода. Да, некоторые пользователи просто скопируют строку из первого и вставят во второе, но даже в этом случае незачем раздувать из этого проблему. Сложная валидация регулярными выражениями — это не дополнительное решение, а только лишний геморрой.

Если же вы все равно не можете успокоиться, пока не проверите адрес на корректность, просто проверьте на наличие в нем символа @. А если чувствуете, что способны на большее — добавьте проверку на точку:

/.+@.+\..+/i

Все, что сверх этого — стрельба из пушки по воробьям.

Примечание переводчика:
Ссылку на эту статью нашел в комментарии к другому переводу. Спасибо jetman!
Перевод: David Celis
@impwx
карма
115,0
рейтинг 63,5
Программист
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (236)

  • +5
    Хоть в чем-то автор и прав, но в целом не соглашусь.
    Некоторые почтовые демоны не будут работать с почтовыми ящиками, описанными в RFC и проверенные стандартными фильтрами языков.

    Да и вообще, какое-то узкое мышление. Многие сервисы высылают письмо с валидацией после регистрации.
    • +21
      Регулярка вообще ничего не гарантирует. Такого адреса может не быть, он может быть набран с ошибкой и так далее и пройти регулярку. Так и наоборот — адрес существующий, а регулярка его не пропустит. В чем смысл таких проверок?
      • +3
        Вероятность, что найдется опечатка регуляркой, намного выше.
        Так как по RFC мы можем иметь почту login@domain. Хороший пример привели ниже про username@gmailcom
        • +1
          Как и вероятность, что адрес не будет пропущен регуляркой вообще. habrahabr.ru/post/175375/#comment_6092863 Мне кажется, что так правильнее.
          • –5
            На практике проблемы с непропущенными адресами не возникает
            • +8
              Возникает. Например существует почтовый сервис на домене i.ua, соответственно почтовые адреса вида mail@i.ua
              Так вот, неоднократно натыкался на то, что такой адрес не всегда проходит валидацию на корректность. Самым ярким примером когда-то стал icq.com — в упор отказывался принимать этот адрес, пришлось заводить специальный ящик на другом сервисе. И это было не однократной проблемой — я несколько раз натыкался на это, когда регистрировал аську, в течении нескольких лет.
              • –21
                Такие хитрые адреса, небось, против спамеров придумали?
                • +12
                  Да чем же он хитрый? Вполне нормальный домен.
                  • 0
                    Если бы спамботы тоже проверяли адреса регэкспами, был бы хитрый…
                • +2
                  Портал позиционирует себя как почтовый сервис с самым коротким адресом. Да и спам туда валится без проблем — не понимаю в чем для вас заключается «хитрость» адреса?
                  • 0
                    Жаль, жаль… спам-боты, видать, регэкспами не проверяют((
                    • 0
                      Т.е. вы хотите сказать, что регэксп один на всех?
                      И у спамеров несколько другие пути получения базы, для них проверка на валидность не так критична, чаще всего все уже проверено тем, кто этот адрес ранее зарегистрировал. Для спамеров это может быть актуально лишь при парсинге сайтов на предмет выкусывания адресов, но опять же — и механизмы другие, и регэксп можно нормальный написать.
                • 0
                  Минусующим: если что, я не спамер, и фишка с самым коротким адресом мне тоже нравится.
            • +4
              Скорее всего, вы просто о ней не знаете: пользователь пробует ввести адрес, не сработало — уходит на другой сайт.
              • +1
                Или регистрирует специальный ящик для регистрации на вашем сайте, которым в дальнейшем не пользуется и теряет его или забывает к нему пароль.
                • 0
                  А потом ящик уничтожается хостером, а потом «возрождается» взломщиками аккаунтов…
                  • 0
                    О том и мой сказ — чем может обернуться «достоинство в 99%».
            • +1
              Если валидация происходит исключительно на стороне браузера, то, да, непропущенный адрес даже не вызывает попытку продолжить регистрацию и не порождает сетевой трафик ;-)
      • +1
        Регулярка гарантирует, что этот адрес не эксплуатирует какие-то уязвимости вашего способа слать письма. Представьте, что там 1000 адресов через запятую, а ваш фреймворк в ответ на такие адреса рассылает письмо на все. Вуаля — через ваш сайт рассылают спам.

        CMS, фреймворков, почтовых серверов и почтовых сервисов в мире очень много, наверняка многие из них уязвимы к какому-нибудь неэкранированному вводу адреса.
        • 0
          Представьте, что там 1000 адресов через запятую, а ваш фреймворк в ответ на такие адреса рассылает письмо на все

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

          Регулярка гарантирует, что этот адрес не эксплуатирует какие-то уязвимости вашего способа слать письма.

          Ну она может быть что-то и перекрывает (вопрос чего больше — хорошего или плохого), но так чтобы прямо гарантирует… Вряд ли. Уязвимость может быть и в рамках экранированного ввода адреса.
    • +4
      Да, в этой идее есть какая-то нотка нигилизма, но основная мысль — не дублировать проверку — мне кажется абсолютно верной. Все равно нельзя знать наперед, насколько сервер, на котором у пользователя его почтовый ящик, соответствует RFC.
      • +21
        Если бы еще все разработчики валидаторов хоть раз видели этот RFC…
        Моё мыло (3@14.by) на ~3% сайтов считается некорректным
    • +4
      А по-моему, заканчивая статью регуляркой, автор противоречит сам себе.
      • +1
        И точка в ней явно лишняя. Однажды пришлось из-за этого переименовывать локальный домен с «local» на «test.local»
    • 0
      Если речь только о регистрации пользователей в браузере, то валидность домена можно без регулярки проверить — через DNS — ajax-запросом на веб-сервер к скрипту, который делает DNS-запросы. Жаль что local-part адреса в реалтайме не проверить, т.к. это (SMTP-коннект к целевому серверу) уже могут быть не секунды, а десятки секунд, а в случае грейлистинга (на целевом сервере) и десятки минут.
  • 0
    Ну вот. А меня еще коробило, когда я сильно упрощал регулярку в одной популярной почтовой библиотеке, так как она не принимала мой же давно используемый адрес.
    А с новыми веяниями в именованием доменов вообще угнаться нереально, даже если захотеть.
  • +5
    Абсолютно согласен.
    Сам перешел с больших регекспов на проверку собачки.
  • –3
    Да ладно, девайсовская регулярка самая оптимальная.

    Отправка письма с подтверждением — потеря определенной доли посетителей.
    • +3
      кстати /.+@.+\..+/i — это почти то же самое, что /\A[^@]+@([^@\.]+\.)+[^@\.]+\z/, только пропускает всякую фигню типа @@@...@@@...@@
      • 0
        А также валидный "@«m@example.com.

        P.S.: тут и хабрапарсер ошибается, если перед собакой не добавить символ.
        • +2
          Да сколько же я будут получать e-mail'ов с моим упоминанием сегодня?
    • +5
      Отправка письма с подтверждением — потеря определенной доли посетителей.

      В зависимости от сервиса и назначения емейла.

      Если нужен 100% рабочий адрес, то по-другому просто никак. Вообще никак.
      • +4
        Валидация никогда не решала проблемы достоверности данных, а только правильности.

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

        Поэтому очень странно звучит совет проверить возможную случайную ошибку средством проверки достоверности (отправкой и подтверждением мейла), когда можно обойтись банальной валидацией.
        • 0
          Не хочется переводить дискуссию в терминологическую плоскость, но откуда взялось «Валидация никогда не решала проблемы достоверности данных, а только правильности. »?

          Для меня валидные данные, это данные, которые удовлетворяют некоторому набору критерий. Критерием, в зависимости от ситуации, может быть, в дополнение к соответствию какому-то формату, и «рабочесть» адреса.
          • +2
            Вы можете при регистрации указать, что вас зовут Петя и вам 33 года, хотя вы Вася и вам 16 лет. Данные правильны, но не достоверны. Валидация тут не поможет. Поможет, к примеру, просьба выслать копию паспорта, заверенную нотариусом, но это же уже не валидация, а верификация.

            С емейлом та же ситуация, подтверждение емейла — это не валидация, а аналог копии паспорта.
            • +6
              Не аналог. Отправка письма на конкретный адрес не подтверждает, что адрес принадлежит вам, она лишь подтверждает, что у вас есть доступ к ящику и что ящик рабочий (а это и есть наша цель).

              Возвращаясь к моему предыдущему комменту: для меня валидация это соответствие некоторому набору критериев.

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

              ps: en.wikipedia.org/wiki/Data_validation

              In computer science, data validation is the process of ensuring that a program operates on clean, correct and useful data. It uses routines, often called «validation rules» or «check routines», that check for correctness, meaningfulness, and security of data that are input to the system.
              • 0
                Ну так дочитайте статью до конца, раз уж начали :)

                Verification Action — это разновидность Post-validation actions. То есть к валидации имеет лишь косвенное отношение.
      • 0
        Ваша регулярка пропустит кирилический домен? А на китайском?
        • 0
          Моя? Я вообще регулярок не писал никаких :-) Я «за» минимальную проверку + отправку письма.
        • 0
          IDN-почта это зло.
          Когда станет добром, тогда будем с ней дружить.
          ПЫСЫ: у меня уже не регулярки, но тем не менее…
  • +3
    В целом, что-то в этом есть. Задумался.
    Но как же те случаи, когда электронный адрес не проверяется отправкой письма с кодом?
    А что если пользователь, регистрируясь, сделал глупую опечатку вроде user@gmailcom (пропустил точку), засабмитил форму и больше никогда не получит письмо с любимого сайта?
    Как по мне, очень спорный вопрос.
    А еще лучше — проверять работоспособность самого ящика (как-то по сети, где-то видел, не разбираюсь в этом — если ошибаюсь — поправьте пожалуйста).
    • +3
      В этих случаях, очевидно, лучше спрашивать пользователя «а не допустили ли вы ошибку в адресе?» и указать на потерянные символы. А под сообщением — ссылка / кнопка «нет, ошибок нет, зарегистрировать».
      • +9
        а проверку опять же регуляркой делать)
        • +3
          Если результат этой проверки можно проигнорировать, то можно и так.
        • 0
          Для JS есть полезный плагин: https://github.com/mailcheck/mailcheck
          Некоторый процент опечаток позволяет избежать
    • 0
      > А что если пользователь, регистрируясь, сделал глупую опечатку вроде user@gmailcom (пропустил точку), засабмитил форму и больше никогда не получит письмо с любимого сайта?

      Ну а как такой вариант — при уходе фокуса с поля ввода email, введенный адрес в фоне передается на сервер, и оттуда для проверки тыркаемся на 25 порт того, что после собаки. Если получаем на клиенте ответ сервера раньше сабмита формы — вываливаем ошибку сразу и не даем сабмитать. Если не получаем — вываливаем после сабмита с просьбой поправить.
      • 0
        > и оттуда для проверки тыркаемся на 25 порт того, что после собаки

        Сорри, тут немного ступил. Вспомнил матчасть, там немного не так работает.
        Но общей идеи это не отменяет, можно просто MX записи проверять на сервере.
        • 0
          Да да, это я и имел ввиду.
        • +1
          exim -bvs
    • +3
      А что если пользователь сделал глупую опечатку user@gmali.com? Какой смысл не давать пользователю ввести возможно правильный адрес, если вы этим все равно не добьетесь отсутствия ошибок.
    • +1
      > А еще лучше — проверять работоспособность самого ящика (как-то по сети, где-то видел, не разбираюсь в этом — если ошибаюсь — поправьте пожалуйста).

      В почтовых протоколах этот функционал есть, но его все поотключали из-за спамеров. Так что остатеся только вариант проверки — послать письмо с кодом.
    • +1
      php.net/manual/ru/filter.filters.validate.php

      Посмотрите примеры, там и проверка на существование домена есть, думаю такие валидации есть и для других языков.
    • 0
      По феншую, вам следует проверить часть «после @» на ее наличие в некоей базе из валидных на сайте. И если ее там не оказалась — намекнуть пользователю на опечатку. Если у вас есть достаточно большая база пользовательских адресов, посмотрите — на сколько часто там возникает ошибка вида gmal.com/gmeil.com в сравнении с пропущенной точной. :(
      • 0
        По такому феншую мне, с почтой, привязанной к собственному домену, было бы неприятна такая дискриминация :)
        Но это скорее частный случай, да.
    • –1
      Кстати, а как много уникальных адресов, с которых регистрируются пользователи? Тех доменов, с которых регистрируется 95% пользователей, не больше десятка.
    • +1
      Я когда статью про SMTP писал, довольно неплохо разобрался habrahabr.ru/post/51772/. Да, по сети можно проверить e-mail адрес на факт существования.

      $ telnet smtp.yandex.ru 2025
      EHLO
      AUTH LOGIN
      ВАШ_ЛОГИН_ПОЧТЫ_В_BASE_64
      ВАШ_ПАРОЛЬ_ПОЧТЫ_В_BASE_64
      MAIL FROM: my-site-email@ya.ru
      RCPT TO: new_user@example.com
      
      

      и факт валидности e-mail new_user@example.com можно определить на этом этапе: если сервер ответит 250 2.1.5 Recipient address syntax Ok; rcpt=... то скорее всего адрес валидный. Само письмо при этом не обязательно отправлять.
  • 0
    Мне кажется, и David Celis, и ответивший на stackoverflow — слишком категоричны. Да, запирать человека в рамки неправильно.
    Но, если вообще отключить проверки, то возникает проблема с опечатками. Банально человек поставит запятую вместо точки — и все. Он будет ждать, в надежде, что сервис тупит, хотя реально письмо уже никогда не достигнет адресата.
    • +3
      Если включить вообще все немыслимые проверки, проблема с опечатками все равно не пропадает.
  • +1
    Для случаев с опечатками и другими подобными вещами нужно предусмотреть повторную отправку письма и возможность исправить адрес. Регулярка страхует, но слабо. А подобных механизм перекрывает все проблемы. Или нет?
  • +2
    qwiufaisjdbvaadsjghb@gmail.com
    Да ладно вам! С этой хренью ни один почтовый демон работать не станет

    Для таких примеров можно брать еще вот этот великолепный email адрес )
    • +12
      Вот, кстати, когда читал так и не понял почему «С этой хренью ни один почтовый демон работать не станет». Что с этим адресом не так?
      • 0
        Не знаю)
        Может быть почтовый демон — это девушка-менеджер в мелкой фирме? Так прямо и представляю как люди, не знающие английского, передают этот адрес по телефону (эс как доллар....)
      • 0
        Полагаю, автор имел в виду, что вероятность существования такого ящика стремится к нулю.
        • +1
          И что из этого следует? :-) Если имя похоже на несуществующее, то реджектить? :-)
        • +1
          Году так в 97-98 я пытался зарегистрировать ящик на yahoo. Не особо надеясь, попробовал комбинации имя-фамилия — как и предполагал такое было занято. Потом начал обрезал буквы по одной из фамилии/имени — нового ответа не получил. В сердцах положил руки на клаву и получил какой-то логин длиной в десяток знаков (на вид совсем как приведённый пример, какого-либо человеческого смысла в нём я не нашёл) и он так же оказался занятым. Положив руки на клаву ещё раз, к тому логину было добавлено ещё столько же символов. Так я стал обладателем ящика на yahoo, которым, по-моему, так и не воспользовался (логин я естественно не записал).
    • 0
      Это не e-mail, это же только домен…
    • 0
      Какое милое напоминание :)
      image
      • 0
        Да, я тоже там поигрался…
  • 0
    Пора бы ручки отрывать за повтор имэйла и за подтверждение регистрации, а не регулярками пользоваться.
    Безусловно, это не касается продуктов, где присутствуют денежные транзакции в том или ином виде.

    • +2
      Пора бы руки отрывать за проверку регулярками! Мой email не подходит почти нигде. На каждом сайте пишу в службу поддержки, что бы исправляли валидацию.

      Правильный пусть:
      — при регистрации спросить email 1 раз
      — позволить войти и пользоваться сервисом!!!
      — отослать письмо с подтверждением и предупреждать пользователя, если он не подтвердил email, но давать пользоваться!
      • +1
        Привет боты с чужими Email?
        • 0
          И что?
          Что изменится для вас?
          • 0
            Ну если вам все плевать на спам, нагрузку (расходы) и связь с пользователями, то незачем.
            Соответственно выигрывают системы, которым не плевать :-) А сейчас вообще уже не то, что email — регистрация через мобильники.
            • +1
              Боже ш ты мой. Что за бред вы несете?
              Пришел бот, зарегестрировался. Вы послали email, вам бот сервис прислал ответ.
              Если под вас будут затачивать бота, то вас и captcha не спасет.

              К тому же, какой ещё спам? Какие расходы на нагрузку от 2-3(10) ботов?
              Мы что, рассматриваем бюджетный форум?
              • –2
                Каждая новая проверка увеличивает стоимость регистрации бота и уменьшает выгоду от него.

                В вашем варианте — она стоит 1 http-запроса с POST-данными.

                В варианте с предварительной проверкой e-mail уже собственный сервер входящей почты, 1 http-запрос, проверка входящей почты и еще один GET-запрос (переход по ссылке).

                Проверка мобильным еще удорожит систему.
            • 0
              Не надо выдавать свои проблемы за проблемы всех пользователей.
              Наличие ботов на сайте — исключительно ваша проблема. И решать ее за счет ваших любимых юзеров — кощунтство и свинство.
              • +1
                Нет это проблемы всех пользователей системы — мне лично боты могут особо и не мешать (подумаешь пара сотен тысяч записей в БД). А вот сотни тысяч спамовых сообщений затронут всех пользователей.

                Мало того неправильно введеный email (с опечаткой) напрямую затронет каждого пользователя, который будет ждать уведомление от сайта не на тот ящик.
          • 0
            Проблема не только в самих ботах, а в том, что нормальный пользователь почтового ящика уже не зарегистрируется, особенно если email потом используется в качестве логина.
      • –3
        Почему бы не завести почтовый ящик с адресом, который будет наоборот почти везде проходить проверки?
        Головной боли меньше будет =)
        • +8
          Пример из жизни:
          my_any_address+filter@example.com

          Так вот FILTER нужен что бы сортировать почту в ящике.
          Но, млин, ЛЬВИНАЯ доля регулярок, не пропускают такой формат.
          • –7
            Hint:
            если бы вы использовали gmail можно было бы обойтись разным количеством точек вместо фильтра
            my.any.address@gmail.com — основной
            myany.address@gmail.com — важная почта

            Что-то в этом духе. Все письма бы всё ещё приходили на ваш ящик, но вы бы смогли фильтровать их по полю To.
            • +4
              плюсик как раз про gmail скорее всего.
              • 0
                И так, и так работает.
              • 0
                Плюсик описан в RFC. И у меня не gmail.
            • +4
              Еще можно по ящику для каждого сайта зарегистрировать, и настроить сбор почты. Пользователю делать больше нечего, ага.

              Для себя давно уже решил: сайт не принимает почту с плюс-фильтром — до свидания, не очень-то и хотелось.

              Если это не стимул для разработчиков, чтобы сделать вменяемую валидацию, то я даже не знаю, за что им платить.
              • 0
                понятно что пользователь таким страдать не будет.

                это workaround для случая когда вам всё-таки нужно пользоваться сервисом, а общаться с саппортом и ждать фикса нет времени.

              • 0
                Сайт, по идее, должен любить юзеров (как и RFC), но кто первый оказался дурак: юзер, заведший ящик с адресом, кажущимся подозрительным всем подряд, или сайтостроитель, забивший в код проверку «не по RFC» (может, просто взявший чужой модуль проверки). И юзер без сайта не умрет, и сайт без него наверняка не закроется…
                • +2
                  Совершенно не имеет значения, «кто первый оказался дурак». Важно, кто остался без денег. И в нашем случае это явно не пользователь.

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

                    По мне так вполне разумно иметь 2 ящика: один сколь угодно «валидный по RFC, но инвалидный на вид», другой — для магазинов. По идее еще надо добавить «для работы» и «для спама», ибо, полагаю, выбор работы нужно делать не по степени следования компании (и всех ее партнеров) RFC на валидность email-адресов, а спам — куда от него денешься.
                    • +1
                      невозможность потратить ваши деньги

                      Это же просто ужасно: мои деньги получат только те, кто предоставляет качественный сервис и внимателен к пользователям.

                      Хотя нет, погодите, это совсем не ужасно, так и должно быть.

                      (Речь не только о почтовых ящиках, конечно.)
                      • +1
                        Вы же сами не хуже меня знаете: потребитель, который вместо покупки (скажем) товара (за чем покупатели и приходят в магазин: выбрать и купить) начинает проверять соответствие систем магазина на RFC, скорее всего вынесет мозг на рубль, а (если и) купит товара — на три копейки. Грубо — нервы не стоят прибыли. Тем более что за выносом мозга, глядишь, раздастся классическое «вы тут все криворукие, я и так у вас ничего не куплю!», и прибыль вообще будет равна нулю.

                        Не то чтобы я сам оправдываю магазины, я говорю о том, что и по городу можно в космическом скафандре ходить, ругаясь, что в иные магазины (который хотят ваши деньги, правда же?) никак не войти, но куда проще быть ближе к параметрам среднестатического покупателя (в этом примере — по росту/весу/обзору), не испытывать проблем, которые (почти) никто, кроме Вас, не испытывает, и сэкономить себе и нервы, и время, и настроение.

                        Если же у Вас специальный рейд — «у Вас отличный магазин — тогда я иду к Вам!», то никто не мешает бороться с ветряными мельницами. Но, сами же понимаете, строго говоря, никто Вам ничего не должен, и за нарушение RFC (как и занесение вашего IP в RBL, например) посадить, и даже оштрафовать, никого не удастся. Интернет, во многом — дело добровольное, и умение уживаться с другими в нем очень кстати.

                        P.S. Желание убить веб-мастера с кривыми руками от этого, конечно, никуда не пропадает, но всех-то не переубиваешь, чего же нервы тратить?
                        • 0
                          Вы все-таки драматизируете, обычно у потребителя нет никакого желания убить, оштрафовать, сжечь в пламени ада и т.п. — жалко времени.

                          Ну и да, если проводить аналогию с настоящим, живым магазином, то подтверждение аккаунта — это как очередь в кассу, или поиски менеджера (консультанта). Покупатели обычно готовы какое-то время подождать, но преимуществом все равно будет пользоваться тот магазин, в котором нет очередей и менеджер всегда на месте.

                          Это не рейд «у вас отличный магазин — тогда я иду к вам», а просто логичное поведение, на мой взгляд. Если сайт или фирма всем своим видом демонстрирует, что мои деньги ей совершенно ни к чему (менеджер пропал неделю назад, очередь у единственной кассы разбивает палатки, готовясь к ночлегу) — имеет смысл пройти 50 метров, там еще один магазин с таким же ассортиментом, зачем тратить время на этот бардак.
                          • +1
                            Вот тут соглашусь. Если видно, что на посетителей плюют, связываться нет смысла.

                            Я только о том, что забитый в скрипт неверный регэксп проверки почтового адреса — это еще не отношение к покупателю, это кривые руки изготовителя сайта. Проверить же при приемке сайта такую мелочь тупо просто забывают. Так что я на такое бы не особо смотрел, если во всем остальном магазин вменяем. А если невменяем, то даже хороший регэксп им (уже) не поможет :)
          • +2
            Аргумент-киллер :) До этого я думал, что мол фигня это все.
            Сейчас сделал вот так:
            list(,$maildomain) = explode('@', strtolower($email), 2); $validEmail = $maindomain AND checkdnsrr($maildomain, 'SOA');
            SOA сделал потому, что некоторые почтовые демоны имеют воркараунд с использованием А если нет МХ, так что не вижу смысла их в этом ограничивать. Мы не W3C чтобы замечания по стандартам делать.
            • 0
              Чтобы исключить лишние ложные отказы, желательно разбивать только по последней собаке.
              • 0
                Я таки упрямый. В плюс я поверил, нельзя не поверить было. Как и в точки и прочее. А вот в IDN и в собаку в имени пользователя я не верю. Не знаю как поведет себя весь почтовый стек, и знать не хочу. На сегодняшний день любой пользователь у которого каким-то образом образовалась почта с дополнительной собакой явно будет иметь другую почту. Вот пусть ее и укажет.
      • –1
        Да, именно так — это самая правильная схема.
      • 0
        Неверно. DDoS очень легко соорудить: регаемся на левые адреса в домене нелюбимой компании, запускаем под этими данными ботов на сайт, кладем его ботами. Сайт, едва продыхивая после ботов, посылает напоминалки на ящики в домене нелюбимой конторы, создавая им доп. нагрузку. Поскольку ящики «кривые» были даны, наш сервер получает массу отлупов, и с ними тоже что-то вынужден делать.

        Как ни поверни, неудачно. Ради чего? Ради удобства юзера, которого куда больше достанут наши почтовые напоминания?

        Логичнее сделать сайт для незалогинившихся на статическим html/js (в т.ч. и форма регистрации), а уже после подтверждения адреса через линк в почте пускать юзера внутрь зоны «не для всех». И сайт лучше DDoS выдержит, и юзер не будет получать кучу напоминалок.
  • +6
    Вкупе с полем для повторного ввода адреса два этих способа позволяют отсеять львиную долю ошибок, связанных со вводом некорректных данных.


    Сколько на хабре было статей по юзабилити форм регистрации, и тут на тебе, повторный ввод email
    • 0
      Ура!
      Теперь я знаю, откуда у таких форм ноги растут!
    • 0
      Повторное поле вызывает легкое раздражение, а непринятие моего валидного адреса почты вызывает полноценный рейдж, так что выбор прост.
      • 0
        Так это же не взаимоисключающие вещи. Избавляемся от регулярок и повтора ввода и вот оно счастье:)
  • +1
    Для удержания клиента эл.почтой не обойдешься. Нужны еще контактные данные, которые надежно «привязаны» к клиенту.

    Пример:
    Используем первый попавшийся сервис временного ящика — «10MinuteMail»
    > Проверка на правильность адреса (регулярка, повторный ввод)… OK
    > Проверка на работоспособность адреса (отправка, подтверждение)… OK
    > Проверка клиента на долгосрочное владение ящиком (?)… N/A


    Вот на этом и «приехали» — остались без клиента.
    А на телефонный номер тоже звонить будете? — а серьезные компании звонят!
    • +1
      ого! Спасибо за ссылку!
    • +2
      Есть сайты, которые не дают зарегаться с почтой от 10 min mail. По крайней мере, у меня однажды не принял. Теоретически можно просто проверять на их домены.
      • 0
        Такого плана сервисов минимум несколько десятков. Можно конечно переодически мониторить базу и добавлять исключения, но стоит ли оно того.
        • 0
          Да, я понимаю, что это бесполезно. К тому сказал, что кто-то вот заморочился.
      • 0
        > Теоретически можно просто проверять на их домены.

        Бессмысленно: на аналогичном сервисе mailinator.com регулярно добавляются новые домены и если при регистрации почта не принимается, не сложно заменить в адресе домен, обычно раз на 3-4-й срабатывает.
      • 0
        ну еще есть asdasd.ru
    • +3
      *не к породившему ветку лично обращаюсь, но в связи с его комментом*
      Если пользователь хочет отделаться от вас одноразовым мейлом — значит ваш сервис нужен ему на 1 раз. Спрашивается: нафига вам в этом случае его контакты? Чтоб задалбывать явно нежелательным спамом? Или вы зарабатываете продажей баз спамерам?
      Не нужно ли в этот момент задуматься и предусмотреть возможность одноразового использования вашим сервисом _вообще_без_регистрации_? Ну хотя бы с ненавязчивой аутентификацией по профилю в соцсетях? (лучше, конечно, вообще без аутентификации)
      Нет, ваше желание удержать клиента понятно, но если клиент вводит одноразовый мейл — он _явно_ не желает быть удерживаемым и ваши поползновения удержать его совершенно точно будут навязчивыми и раздражающими.
      К сожалению, в инете очень много сайтов, на которых требуется регистрация для выполнения явно одноразовых действий. Нафига? Очень раздражает.
      Оффтопик, конечно, но не удержусь от общих пожеланий:
      — 100 раз подумайте перед тем, как заводите форму регистрации на вашем сайте: для каких действий она необходима? точно-точно необходима? необходима вам или пользователю? не перевесит ли удобство использования вашего сервиса без регистрации сомнительную вероятность возвращения пользователя на сервис после напоминания спамом?
      — 1000 раз подумайте перед тем, как потребовать для регистрации мейл, или, хуже, телефон: он точно вам необходим? пользователь точно обрадуется вашему письму/звонку? может, обойдетесь парой логин/пароль? может сделаете ввод мейла хотя бы опциональным (тот, кто боится забыть пароль и потерять доступ к аккаунту — пусть вводит, остальные зарегистрируются заново, делов-то!)?
      — а может стоит сделать альтернативную аутентификацию через соцсети? особенно, если боитесь спамеров и флудеров. фейковый аккаунт в основных соцсетях завести уже сложнее, чем левую почту, всю грязную работу по отсечению флудеров фейсбушки и вконтактики уже делают за вас. но это только на крайний случай, когда вообще без аутентификации — никак.
  • 0
    Конечно, для проверки email-адреса регулярные выражения использовать не следует, ведь для этого есть Zend\Validator\EmailAddress (ранее Zend_Validate_EmailAddress). ;-)
    • +3
      или даже filter_var()
    • –1
      PHP и Zend понятия не имеют, что у вас разрешена регистрация только с известных почтовых систем (gmail, яндекс и т.д.). PHP и Zend выполняются на сервере и скорость исправления ошибок пользователем начинает стремиться к бесконечности вместе со скоростью и качеством интернета. А как следствие и конкурентоспособность системы тоже стремится к нулю.
      • 0
        Это что ж за сервис такой, где не то что RFC-compliant адреса не принимают, а вообще «разрешена регистрация только с известных почтовых систем»? Подскажите, куда ходить не надо.
  • +3
    В статье перегиб. Проверять надо, но, возможно, не весь адрес, а собаку и после нее.
    Давно использую вариант проверки: первая собака, после нее домен (минимум одна точка) и запрос в DNS на существование домена. Домены храню после проверки локально для уменьшения запросов — по сути 10-20 почтовых систем покрывают 80-90% адресов пользователей.
    • 0
      запрос в DNS на существование домена

      Как именно? MX?
      • +3
        Если полноценно, то проверять надо налчие MX или A, ибо почтовик при отсутствии MX записи имеет полное право слать на A.
        • –3
          Соответственно достаточно проверять просто А, проверка ещё и МХ в данном случае будет избыточна.
          • +3
            А не обязан существовать.
            • 0
              RFC 5321 говорит нам:
              If an empty list of MXs is returned,
              the address is treated as if it was associated with an implicit MX
              RR, with a preference of 0, pointing to that host.

              Так что тут двоякая ситуация, если нет MX — шли на A, но если нет A — проверяй MX.
              Я, правда, слабо представляю, у какого процента доменов нет А, но есть MX.
              • 0
                У доменов, которые держат специально для емейла.
          • 0
            Лучше уж проверять только MX и не проверять A даже если MX-а нет.
            Ни та ни та запись не обязательна.
            Практика показывает, что MX есть примерно в 95-97% случаев, остальные как правило или не интересны как клиенты или писали почту-домен для «отмазки».
            Опять же (что писал выше): 10-20 популярных почтовых систем покрывают 80-90% пользователей, а у них (систем) MX есть (да и ничего не мешает их руками добавить в справочник). Тут конечно мы не рассматриваем абстрактную социалочку для люителей совего домена :)
            • 0
              Тогда уж не спорьте и проверяйте по SOA как я всегда делаю.
              А то мы так и до спамхаОса договоримся.
        • 0
          Можно ссылку? Всегда считал, что почта только на MX шлется.
          • 0
            Ну если беглым поиском — то RFC 5321 пункт 5.1.
            Это то что бегло откопал, писал в основном по памяти.
          • 0
            Да, она самая, 5321
            The lookup first attempts to locate an MX record associated with the
            name. If a CNAME record is found, the resulting name is processed as
            if it were the initial name. If a non-existent domain error is
            returned, this situation MUST be reported as an error. If a
            temporary error is returned, the message MUST be queued and retried
            later (see Section 4.5.4.1). If an empty list of MXs is returned,
            the address is treated as if it was associated with an implicit MX
            RR, with a preference of 0, pointing to that host.
            If MX records are
            present, but none of them are usable, or the implicit MX is unusable,
            this situation MUST be reported as an error.

            (так, что-то я RFCшками расцитировался, не к добру)
  • +11
    Люто плюсую. Просто бесят эти валидаторы, руки бы поотгрыз разработчикам и администраторам форумных движков. Был даже такой случай:
    Ввожу example.com@gmail.com (example.com — мой сайт, адрес регистрировался еще тогда, когда я не умел делать почту на своём домене). Невалидно. Наверно точка перед собакой межает. Ладно, попробую другой.
    a@example.com — тоже не валидно. Да что за фигня? Адрес не может состоять из одной буквы? Ладно, попробую пойти на крайние меры, ведь у меня завалялся ящик с mail.ru еще с тех времен, когда у меня появился компьютер с модемом.
    example@mail.ru — Ответ валидатора: «Не допустимый домен». Типа с майл ру много спама. Ненависть.

    Адовый ад. Еще помножив моё негодование на дебилоидность остальной части регистрации любого форума, мозг начинает вскипать.

    Регистрационная форма на форумах — это вообще уникальная тема. Недавно зарегистрировавшись с пятого раза на одном из форумов, в ответ мне выдали страницу с примерным текстом: «Администрация должна проверить ваши данные, ждите приглашения на почту».
    • –3
      Возможно кривость одной конкретной реализации валидатора не означает то, что проверка данных на корректность ввода и отсутствие механических ошибок-описок не нужна в принципе? Вопрос не в самой валидации, а фанатизме некоторых — не более того.
    • 0
      Кстати как минимум для гмейла точку в логине можно пропускать.
      • 0
        Для гмейла user.name и username — это один логин?
  • +1
    А что делать в том случае, если пользователь просто ошибся в написании адреса, а ваше регулярное выражение его не помогло?
    Не думаете-ли вы что человек просто не получив письмо с активацией из-за ошибки в написании просто про вас забудет?
  • +7
    /.+@.+\..+/i

    Мне кажется, это вредный регексп.
    Он не пропустит почту в TLD навроде «user@localhost» или «user@localdomain», хотя в корпоративных системах без выхода в большой Интернет вполне могут быть такие ящики. А если учесть возможность регистрации TLD частниками — так и вообще.
  • –26
    Зачем нужна проверка e-mail:

    1. Для предотвращения SQL-инъекций.
    2. Для предотвращения XSS-инъекций.
    3. Для предотвращения отправки email по локальному адресу вашей организации (user@localhost, user@yourdomain и другие ваши адреса).

    и т.д.

    Защита от первых 2 атак может быть организована на другом уровне (проверка всех входных параметров и плейсхолдеры), третья атака специфична именно для этого поля, т.е. @ и. на сервере нужно проверять, как минимум.

    Кроме атак, проверка e-mail нужна для исправления опечаток и реализовывать это нужно на клиенте. И тут уже логика совсем другая — не защита, а помощник. Т.е. например ввод по маске (без кривых символов [] и т.д.), подсказка домена, подсказка доменной зоны и т.д. Ведь если пользователь вобьет не свой e-mail, то скорость его вовлечения в нашу систему станет гораздо большей или он вообще не попадет к нам. Т.е. проверка email на клиенте — маркетинговая фишечка.
    • +20
      > 1. Для предотвращения SQL-инъекций.
      Фейспалм.
      • –30
        Так напрягают люди которые говорят какой-то бред и акценцируют коммент привычным для троллей словом(((
        • +6
          Защита от первых двух типов атак должна быть организована на другом уровне. Как, впрочем, и от третьего типа.
          Проверка email нужна исключительно чтобы пользователь не опечатался в адресе.
  • –1
    Горе от ума! А если письмо уйдёт на сервис фэйковых адресов для регистрации?
    • +1
      И что?
      Я почти везде вбиваю все данные фейковые.
      А если вам придет адрес bla-bla-bla-spam@mail.ru вместо test123@mailforspam.com, для вас что-то изменится?
      • –3
        Вы не поняли — мне, как регистрирующемуся, ничего не придёт. Я просто сгенерирую ящик на 5 минут, только для того, чтобы потом пройти по ссылке для подтверждения регистрации. И посему, описаная выше метода опять-таки не на 100% работоспособна.
  • –1
    Зачем вы придумываете велосипед?
    Есть же RFC на проверку почты RFC-822 :-)
    • –2
      RFC — это всего лишь конкретные предложения в конкретный момент времени. В будущем они непременно устаревают и кто-то предлагает лучший вариант.
      Если вы видите себя только в роли статиста — не стоит другим навязывать такой жизненный подход.

      Велосипед — это точный повтор функционала предыдущей системы. И если мы добавляем новые проверки email или исключаем старые относительно текущего RFC, то это уже нельзя считать велосипедом. Это — инновации. Они могут быть хорошими и плохими. Хорошие (при одобрении ведущих разработчиков) станут новыми RFC.
      • 0
        Вы явно не уловили сути моего высказывания. Я про то, что нет ничего иновационного в отключении проверки на стороне клиента. А если действительно нужна полная подержка стандарта имен почтовых адресов, то вполне приемлимо (если вы не любитель) использовать готовое решение предложенное стандартом.
    • +1
      RFC 822: Obsoleted by: 2822
  • 0
    Вот уж что называется — вопрос подхода.
    Пользователю, по большому счету, все равно что и как у нас происходит внутри, ему нужно чтобы просто все работало и он получал информацию с наименьшими усилиями.
    Поэтому считаю что нужно приложить на стороне разработчика максимум усилий чтобы пользователю было комфортно.
    На большинстве последних проектов нет подтверждения e-mail, а валидация происходит на стороне клиента через проверку на наличие точки, собаки, и содержание более двух символов между ними; и этого считаю достаточно.
    • +3
      А как же mail@i.ua?
    • +2
      через проверку на наличие точки, собаки, и содержание более двух символов между ними; и этого считаю достаточно.


      Хабраюзер ICELedyanoj с удовольствием пообщался бы с вами, но ваша проверка не пропустила его адрес
      • 0
        Я бы мог оправдаться что на украинский рынок не рассчитывали в принципе, но это звучало бы глупо, поэтому признаю ошибку.

        Думаю сильно не городить лес, а просто изменить в алгоритме количество символов между собакой и точкой до «больше или равно один символ», таким образом со всеми сможем пообщаться.

        Честно, не знал что бывает почта на доменах из одной буквы. Спасибо, хабр.
        • 0
          Вот-вот, icq.com в свое время тоже не знал, а всего лишь достаточно заглянуть в спецификацию.
  • 0
    Возможно на сравнительно небольшом потоке пользователей и рассылок такой подход подойдет.

    Однако, в случае если доп. проверка отфильтрует 5-10% ошибочных email-адресов, то будет сэкономлено соответствующее количество ресурса затраченного на генерацию писем (как минимум).
    • +1
      Зашел к вам директор некой фирмы Н, и его email не подошел.
      Вы потеряли достаточно крупного клиента — поздравляю.
      • 0
        Если у вас «сравнительно небольшой объем поток посетителей», то этой действительно будет проблемой.

        В ином случае, надо считать что будет выгодней: сэкономленные ресурсы + в целом более качественная база против получения аккаунтов директоров неких крупных фирм Н с невалидным email-адресом.
        • +2
          Никакие «сэкономленные ресурсы» не стоят потери одного клиента.

          Что экономим-то, строчку в БД? Цена гигабайта дискового пространства — 1 рубль.
          • +1
            Потратим сто тыщ трудо-часов, чтобы сэкономить 2 DNS запроса и 1 SMTP!
            Даешь оптимизацию ради оптимизации! Сервер должен быть экономным!
            • 0
              SMTP запрос только для проверки валидности email-а — это очень дорого.

              Экономия будет:
              1. на CPU при генерации писем (случай, когда письма под пользователя, а не у всех одинаковое)
              2. времени: почтовики будут охотнее принимать письма от вашего MTA, если не пытаться им в поле to всякий шлак отправлять
  • +4
    Забавно, прочитав название и первое предложение, я понял, что это перевод.
  • НЛО прилетело и опубликовало эту надпись здесь
    • 0
      habrahabr.ru/post/175375/#comment_6093383

      Все те же 2 причины:

      1. На сервере для уменьшения нагрузки на СМС-шлюз (ведь ему придется отсекать ваши невалидные адреса).
      2. На клиенте для исправления опечаток и повышения конкурентности системы.
      • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          2. И как вы потом на такие данные пошлёте смс?

          Однотипность данных в системе даже если не используются рассылки — важная вещь
          Вдруг вы потом решите добавить сортировку по телефону? или захотите проанализировать каких операторов используют ваши клиенты?
          • НЛО прилетело и опубликовало эту надпись здесь
            • +1
              ну если делать посимвольно то бред,
              А если скажем сгруппировать по странам (коду страны, коду города) то уже можно получить симпатичный такой справочник клиентов
            • +1
              есть и более типичная задача. Вы просто хотите форматированно отображать телефон, с пробелами между кодом страны/города и самим телефоном
              и если вы заранее не позаботились о том чтобы у вас в поле телефон был «валидный» телефон — для решения этой задачи вам нужно будет пытаться обработать эти случаи с разбиением запятой, пробелом, «или». а может человек вообще ввёл «нет» в это поле.
        • –1
          А если он в телефон хочет еще имя любимой кошечки засунуть и логин свой и email, а в email логин и телефон?)

          Если вам все равно кто у вас что делает и вам не нужна связь с пользователями, то вы, безусловно, правы :-)
  • –1
    А не забыли ли вы о пользователях в этой погоне за простотой кода?

    Регулярка там или нет — я хочу чтобы в случае опечатки форма мне помогла исправить ошибку до того как уйдёт письмо на несуществующий адрес. Ведь в этом случае мне как минимум придётся заполнять всю форму регистрации заново, и это если я замечу что была опечатка в адресе. А я могу не знать и просто сидеть и ждать когда же мне дойдёт письмо.
    • 0
      В итоге посыл должен быть другой — используйте регулярки, но вместо того чтобы блокировать регистрацию с «неправильным» адресом — выводите пользователю предупреждение или требуйте подтверждения (на форме) что он всё ввёл корректно.
  • 0
    Это что, неделя email валидации? Уже третья или четвертая статья на эту тему.
  • 0
    Потому что не надо делать тысячу раз одно и тоже. Код хорошей проверки уже давно вынесен в гем, например, github.com/alexdunae/validates_email_format_of.

    Регулярка помогает уменьшить количество ошибок при вводе адреса. В большинстве случаев адрес критичен: восстановление пароля, получение покупок итд, в некоторых не кричен (публичный имейл на github вобще не проверяется).
    • 0
      Не существует хорошей универсальной проверки email. Для каждого проекта есть свои задачи и свои требования и своя проверка email. Да, существуют более менее универсальные решения, но никак не одно на всех.
    • +1
      Просмотрев кож вижу что только для английского кириличный почтовый адрес пошлёт лесом.
  • +4
    В любом ЯП есть уже более-менее традиционнные библиотеки, реализующую «ту самую» проверку емайла регуляркой на два листа. Мое мнение — надо использовать их, а не придумывать свой велик. Почему — это уже вопрос юзабилити. Как верно было подмечено выше, в случае ошибки в адресе или даже сознательной попытки не палить ящик, юзеру не придется проходить регистрацию заново, его просто пошлют на этапе заполнения формы. И кстати, в отличие от самопальных регулярок, данный способ совсем не требует умственного напряжения.
    Пользовались перловым Email::Valid в достаточно «крупной международной компании», жалоб не было. Упомянутые в комментах фильтры с плюсиками — тоже работали, что добавляло удобства уже нам, разработчикам. Так что все хорошо.
  • +2
    Полностью согласен.
    В оправдание своему мнению вспоминается один случай.
    У меня есть почтовый ящик в зоне .name
    Пробовал зарегистрировался толи на сайте «Каро», толи на сайте «Киномакс», сейчас уже не помню, и не смог! А знаете почему? Потому, что средствами JS адрес проверялся по регулярке и в этой регулярке было написано, что количество символов в доменной зоне не должно быть больше 3-х, а у меня их 4. Да, и, кажется, там ещё стояло правило, что до знака @ должно быть не менее 3-х символов, а у меня там 1 символ. Пришлось немного переписать функцию проверки адреса и только после этого я смог зарегистрироваться. Ладно хоть на стороне сервера не было никаких конфликтов с форматом адреса моей электронной почты.
    Вот такая вот история.
    • –5
      А некоторые сайты вообще открываются с 500 ошибкой и что? Есть кривые руки — подход от этого не становится неправильным.
      • +1
        Согласен, что проблема не в подходе. Проблема как раз в кривых руках. Но если бы разработчики этого ресурса не стремились следовать этому подходу, то их криворукость не была бы такой очевидной.
        • –8
          Бред, у них были бы XSS и SQL дырки.
          • +2
            Вы опять. Какие XSS и SQL дырки, как это вообще связано с емейлами?
            • –7
              Что именно вы не хотите понять? Что любая передаваемая от пользователя и сохраняемая информация может содержать уязвимости? Что если говнокодер уберет проверку регуляркой, то это минус одна защита от этих атак?
              Или что вам просто хочется докопаться до чужих мыслей так как нет своих (троллинг)?
              • +5
                любая передаваемая от пользователя и сохраняемая информация может содержать уязвимости

                жесть
              • +5
                Информация не может содержать уязвимость. Не нужно защищаться от атак!

                Нужно соблюдать формат данных тех систем, которые вы используете. Если вставляете данные в базу, просто соблюдайте формат SQL! Если выводите данные на страницу, просто соблюдайте формат html! Если передаете строку в url, просто соблюдайте формат url! Это ведь так просто.
                • –11
                  О боже, хабр такой хабр.
                  :-) Формат SQL позволяет послать запрос вида:

                  insert into users(email) values(«sssss»);delete from table users where (email="");

                  И если пользователь передает sssss");delete from table users where (email=", то ЭТО БУДЕТ верным запросом с точки зрения БД.

                  Тоже самое с HTML.

                  Как раз форматы этих систем позволяют использовать их в негативных целях.

                  Ахахаххх, т.е. url нужно проверять на формат URL, а email не нужно?

                  Товарищ перестаньте нести бред :-)
                  • +6
                    Очень жаль что вы меня не слышите. Формат SQL явно говорит о том, что специальные символы в данных должны быть экранированы. Именно это и есть соблюдение формата. А то что описали вы — нет.
                    • –10
                      ЫЫЫ, т.е. вы утверждаете, что форматы умеют разговаривать?) А вы уверены, что понимаете значение слова формат, раз докапываетесь именно до формулировок, а не до сути?
                      • +5
                        ЫЫЫ (((
                        • –8
                          Ну тролли обычно заканчивают рассуждения именно таким сильным аргументом.

                          Для всех остальных замечу, что формат — это структура данных, а не спецификация или рекомендации по его использованию. А приведенный мною пример полностью соответствует формату SQL, но не следует рекомендациям по его использованию. Формат обеспечивается средствами используемого языка и несоблюдение формата на их совести. А вот я говорил именно о людях, которые не соблюдают рекомендации. И инъекции именно на их совести (при этом формат абсолютно соблюден).
                          И это абсолютно разные вещи, а товарищ homm просто попробуйте разобраться в терминологии прежде чем использовать какие-то слова или перестаньте троллить :-)
                          • +6
                            Приведите пример «ломающий меня полностью».

                            $db->query('select * from users where name = ' . $pdo->quote($_GET['name']));
                            

                            $db->query(sprintf('select * from users where id = %d', $_GET['id']));
                            

                            echo '<h1>Hi ' . htmlspecialchars($_GET['name'], ENT_QUOTES, 'utf-8') . '</h1>';
                            
                            • –8
                              Вы понимаете о чем вообще разговор или просто хотите что-то умное ляпнуть?))

                              Так вот, речь идет о том, что базы данных не обеспечивают нужного нам типа данных, они универсальны — в них есть строки, целые числа и т.д. Очень малое число БД реализует тип Email.
                              И этот недостаток БД никак не означает, что мы должны позволять сохранять вместо E-mail любую экранированную строку. Нет, просто мы должны эти типы описывать самостоятельно. И ограничения им выставлять тоже самостоятельно.

                              А вы хотите все типы приравнять к одному и выдать это за хорошее решение :-) Почему бы тогда вам вообще не писать и числа в тип CHAR, и вообще ну их все эти типы — пусть будет один тип «Строка» и плевать, что там будет храниться — нам ведь главное бред написать на хабре, а не эффективные системы создавать, правда?) А если есть возможность нажать «Минус» — тут наше ЧСВ вообще лопнет от счастья :-)
                              • +8
                                Бред, у них были бы XSS и SQL дырки.

                                любая передаваемая от пользователя и сохраняемая информация может содержать уязвимости

                                И если пользователь передает sssss");delete from table users where (email=", то ЭТО БУДЕТ верным запросом с точки зрения БД.

                                Ваши слова?

                                Так передайте же в мой код «информацию содержащую уязвимости». Давайте, смелее!
                                • –10
                                  Где я писал, что любая система подвержена SQL-инъекциям, а весельчак?
                                  В моем примере ИНФОРМАЦИЯ содержит инъекцию.
                                  И есть тысяча и один случай когда это срабатывало.

                                  Где я писал, что невозможно написать защищенную систему?
                                  С кем вы вообще спорите? С собой?

                                  И да, кстати ваш код тоже говно :-)
                                  • +7
                                    > И есть тысяча и один случай когда это срабатывало.

                                    Это случалось именно потому что у разработчиков была такая же каша в голове как у вас, с информацией содержащей уязвимости и емейлами с инъекциями. Если бы они просто придерживались формата, ничего такого бы не происходило.
                                  • +2
                                    И да, кстати ваш код тоже говно :-)

                                    Что же в нем такого плохого?
                              • +6
                                Если пользователь хочет себе ник
                                s');delete from table users where 1=1 --
                                , то это его право.
                                Если он считает, что его email
                                s');delete from table users where 1=1 --@a.b
                                , то может теперь так можно.

                                Если вы считаете, что уязвимость может быть в данных — вы не правы.
                                Уязвимость не в данных и даже не в протоколе в данном случае. Уязвимость в коде с конкатенацией данных в запрос. Неужели где-то еще нельзя использовать плейсхолдеры (не важно как они обрабатываются — экранируются библиотекой или с использованием полноценного подготовленного запроса)?
                                • –7
                                  Вообще то в любой нормальной системе есть правила. В том числе и на сайтах.

                                  И обычно в правилах написано, что пользователь должен вводить свои данные. А задача разработчиков создать систему в которой он не сможет нарушить эти правила. И если человек вводит вместо своего e-mail опасный код, то он нарушает правила сайта.
                                  Мало того. Этот вопрос регулируется на уровне законодательства. И если этот опасный код сотрет нам базу, то этот человек станет преступником.

                                  Так что нет пользователь не имеет права вводить что угодно на моем сайте.

                                  И для любителей придираться к формулировках отвечу, что данные это не активный элемент и не совершают действий сами по себе и любой нормальный (не тролль) человек поймет, что говоря про уязвимость в данных — имеют в виду уязвимость при работе с этими данными.

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

                                  Отсюда все эти придирания к формулировкам, всеобщее сплочение и несение бреда и т.д.
                                  • +3
                                    >> И обычно в правилах написано, что пользователь должен вводить свои данные. А задача разработчиков создать систему в которой он не сможет нарушить эти правила. И если человек вводит вместо своего e-mail опасный код, то он нарушает правила сайта.

                                    Мало кого это останавливает.

                                    >> Мало того. Этот вопрос регулируется на уровне законодательства. И если этот опасный код сотрет нам базу, то этот человек станет преступником.

                                    Код сотрёт злоумышленник. Но по чьей вине он смог это сделать? По вине того самого говнокодера, который не позаботился об элементарной защите.
                                    • –6
                                      Вы вообще о чем говорите? Сначала вы начали говорить, что пользователь имеет право вводить все, что ему заблагорассудиться — теперь о том, что все пользователи — хакеры. Вам доказать, что и это бред или что?

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

                                      Сначала вы пишите, что вам плевать, что у вас в базе вместо email будет произвольная строка, потом говорите, что виноват в этом будет говнокодер. Т.е. обвиняете сами себя :-)

                                      И еще раз повторю, никто не делает идеально защищенных систем. Просто в IT-сфере в целом легче защищаться в целом. Но никто не будет делать все автомобили бронированными с расчетом на то, что в них могут пульнуть из гранотомета :-)
                                      • +5
                                        >> ужасный подход с использованием плейсхолдерами
                                        И тут я попал в ступор, минут на 5.
                                        Мне вас действительно искренне очень жаль.
                                      • 0
                                        Сначала вы пишите, что вам плевать, что у вас в базе вместо email будет произвольная строка, потом говорите, что виноват в этом будет говнокодер.

                                        Как-то туго у вас с логикой.
                                        «Говнокодер» как раз будет виноват в том, что вместо того, чтобы записать в базу произвольную строку, он выполнит черт знает что.

                                        Но никто не будет делать все автомобили бронированными с расчетом на то, что в них могут пульнуть из гранотомета

                                        Но вы предлагаете сделать автомобиль таким, что он развалится если в него сядет леди Гага или Джигурда.
                                        Такие люди вам обычно не встречаются, но они по сути обычные люди. Почему автомобиль разваливается?
                                        Строки с кавычками — это такие же строки, хоть вы их и не ожидаете.
                                  • +1
                                    Вообще то в любой нормальной системе есть правила.

                                    И они не должны определяться кривизной рук разработчиков.

                                    И если человек вводит вместо своего e-mail опасный код

                                    Не бывает опасного кода в пользовательских данных. Бывает не правильное использование инструментов.
                                    И когда на форумах (даже программистских) в постах вырезаются угловые скобки хочется убивать.

                                    И если этот опасный код сотрет нам базу, то этот человек станет преступником.

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

                                    Отсюда все эти придирания к формулировкам


                                    Я, кстати, заметил только одну:
                                    т.е. вы утверждаете, что форматы умеют разговаривать?

                                    При этом не верную ни по сути ни по форме (см. определение).
                                  • +2
                                    Так что нет пользователь не имеет права вводить что угодно на моем сайте.

                                    Тогда проверки совсем не нужны. Любой «неправильный» ввод — и в тюрьму. Отлично же!
                            • +1
                              Ну, лично я считаю, что надо использовать $stmt = $pdo->prepare($parameters); и $stmt->execute();. Оно гораздо более защищено от инъекций.
                              • +1
                                Я знаю о prepared statements. ИМХО, не так важно какой подход использовать. Главное — понимать что и зачем Вы делаете. Вот сейчас кто-то прочтет Ваш комментарий и побежит везде писать:

                                $stmt = $pdo->prepare('select * from users where name = ' . $_GET['name']);
                                $stmt->execute();
                                

                                Он же прочитал на Хабре, что:
                                Оно гораздо более защищено от инъекций.

                                :)
                                • 0
                                  О нет, этот некто забыл $parameters передать! :-)

                                  На самом деле, я надеюсь, что этот кто-то перед тем, как полезет менять mysql_execute($unsafeSQL) на $stmt = $pdo->prepare($unsafeSQL); $stmt->execute(); заглянет в справочник хотя бы по пхп. Не говоря уж о более специализированных статьях и презентациях.
                                  • 0
                                    Будем надеяться.

                                    А еще Bill Karwin написал книгу «SQL Antipatterns» — горячо рекоммендую.
                                    • 0
                                      Книгу не щупал, но судя по презентации, там есть что почерпнуть.

                                      Как показала практика, есть куча программистов, которые даже тезисы, изложенные в презентации, не способны последовательно применять без контроля и пинков.
                                      • 0
                                        Книга является более расширенной версией этой презентации. Или презентация — кратким конспектом книги. Мне очень понравилось, и по стилю изложения, и по содержанию. Очень емко и доступно. Кстати, читать лучше в оригинале, перевод — не понравился.

                                        P.S. Ваша ссылка на презентацию ведет на 404.
                                        • 0
                                          Пардон, не проверил. Дядя по всей видимости из шары убрал файл, а линки не почистил. Пичалько…
                                          Вот она же на slideshare, если вдруг кому-то надо :-)
                  • +2
                    >> insert into users(email) values(«sssss»);delete from table users where (email="");
                    Если вы делаете именно так в своих проектах, то мне вас искренне жаль.
                    Я не знаю на сколько надо быть говнокодером, чтобы не предусмотреть защиту от приведённого вами примера.
                    Все данные из всех полей, не важно мыло там вводится или текст, должны быть обработаны перед тем как вставлять их в запросы. Это же очевидно.

                    Или используйте плейсхолдеры ;)
                  • +1
                    А что, за отклонение пользовательских данных по причине наличия ключевых символов еще не расстреливают?
                    И когда перестали расстреливать за конкатенацию данных в sql-выражения?

                    Я, кажется, что-то пропустил.
  • 0
    Статья с идеей разряда «из крайности в крайность».
    Поддерживаю системы как с верификацией емейла (через отправку письма), так и без нее.
    Системы без верификации позволяют сделать регистрацию мгновенной, что выглядит довольно эффектно, если у всех конкурентов всё «правильно» с отправкой письма, которая замедляет и усложняет момент регистрации как по вине вашего сервиса, так и по вине почтовой системы клиента (письмо долго не приходило, письмо попало в спам и т.п.).

    Правда, для минимизации времени регистрации можно требовать ввод емейла не во время регистрации, а после.
    Тогда можно сделать эту верификацию «с чувством, с толком, с расстановкой». Но, во-первых, это применимо не ко всем системам (для многих отстутствие емейла критично), во-вторых не многие заказчики могут привыкнуть к отложенному заполнению регистрационных данных (у многих в голове висит ярлык, что клиент при регистрации должен полнять все-все свои данные).

    Золотой серединой вижу проверку на корректность домена и на наличие MX-записей.

    P.S. также ничто не мешает вести статистику случаев, когда валидация не пропускает те или иные данные. Грешу этим. Очень помогает совершенствовать проверки до того момента, как разъяренные клиенты начнут звонить в вашу компанию.
    • 0
      Мне, как пользователю, удобнее с моментальной регистрацией, более того, мне, как пользователю, зачастую удобнее вообще без регистрации! Вот многие инет магазины позволяют сделать заказ вообще без регистрации, и это правильно, я быстрее закажу в таком магазине, чем в том, в котором мне придётся сидеть и ждать письма.

      Золотой серединой вижу проверку на корректность домена и на наличие MX-записей.

      RFC 5321 с вами не согласна:
      If an empty list of MXs is returned,
      the address is treated as if it was associated with an implicit MX
      RR, with a preference of 0, pointing to that host.
  • +1
    Даешь неделю регулярных выражений на Хабре!
  • 0
    Отправлять письма для проверки емейла при регистрации пользователя — это нормально. А если нужен простой сервис подписки на новости сайта? Если регистрацию адресов делать через подтверждение емейла, то клиентов будет в разы меньше. Зачем их терять введением избыточно сложных процедур?
  • 0
    А если чувствуете, что способны на большее — добавьте проверку на точку

    Точка необязательна: vasya@ru — вполне корректный адрес.
  • –2
    Поддерживаю автора. В емейле неизменно только одно — наличие @. Даже точка в домене может быть излишня во всяких там интранет-системах.

    А вот на счёт опечаток, рекомендую посмотреть на github.com/kicksend/mailcheck
    Это работает лучше самых сложных проверок на regexp'ах.
  • 0
    Это требуется для того, чтобы удостовериться, что я действительно имею доступ к почтовому ящику, на который регистрируюсь.


    asdasd.ru
  • –4
    Только на @ проверять я думаю не хорошо. Письмо шлют как правило через сторонню функцию, библиотеку, класс и т. д., в итоге можно получить инъекцию в тело письма и отправлять таким образом спам например. Или ещё к примеру встроить в тело письма какую-либо ссылку и в итоге от того же хабра получить письмо с изменённым текстом письма со встроенной XSS или CSRF или ещё чего по хуже.

    Это всё в то случае, если эта сторонняя библиотека, через которую отправляют письмо никак не реагирует на не валидные данные. Но думаю так или иначе найдутся такие, не сторонние так свои. У которых «защита» будет сломлена при переключении своей проверки, перед отправкой, только на @.

    Это конечно в теории. Или я в чём-то ошибаюсь?
  • +1
    Можно было бы написать короче:
    «Не проверяйте e-mail сложным алгоритмом. Ведь всегда, когда вам нужна такая проверка, обладатель этого e-mail может вам помочь».
    Привет от разработчиков распознавалки :)
  • 0
    В чем то автор прав. Большая часть всяких валидаций ни к черту не упала, но каждый милипизерный сайт хочет, чтобы именно на нем зарегились, да еще при этом попросит отдельно юзернэйм ввести, да именно по его правилам, так что свой любимый не выйдет использовать, и пароль любимый не даст опять же потому что он каким то локальным проверкам не удовлетворяет.

    Если вам действительно нужны валидные емэйлы для регистрации на сайте, шлите письмо, правильно чел говорит.

    Конечно если дело касается платежей, то надо данные проверять, но тоже без фанатизма
  • 0
    Действительно, не используйте валидацию email, тем самым вы сэкономите 2-5 минут своей жизни с каждого проекта.
  • 0
    Как раз сейчас пишу такую проверку, но тока на пользовательской стороне. Ну раз уж на то пошло будем проверять просто на наличие @
  • 0
    Сранно, что до сих пор никто не упомянул про regexp-based address validation написанную под RFC822 (RFC2822) — www.ex-parrot.com/pdw/Mail-RFC822-Address.html :)
    • 0
      Хотел упомянуть, но вы меня опередили.
      Скажу только, что я бы наверняка не стал это копипастить в свой код…
  • 0
    Ждем пост про валидацию url, даты и почтового адреса при помощи регулярных выражений ;))
  • –1
    Ещё бесит, когда в поле ввода умники макс количество символов прописывают… Не, ну мне страничку поправить не сложно, но неприятно.
    • 0
      Странные какие-то случаи, не понимаю негодования. Когда ты последний раз видел поле для ввода e-mail с максимальным количеством символов? Homepage не в счёт.
      • 0
        la2.mmotop.ru к примеру. Пару лет назад было ограничение на длину емайла. Сейчас осталось только ограничение на длину пароля.
  • –1
    Писать или не писать regexp для проверки e-mail? А вот смотря зачем. Давайте подумаем.

    Если для сервиса с двухступенчатой валидацией — можно вроде бы и не писать, но давайте поставим себя на место легитимного пользователя, который хочет действительно зарегистрироваться на ресурсе и воспользоваться его услугами? Как он узнает, что он опечатался в адресе при регистрации и не сможет зарегистрироваться? Сколько он будет ждать прихода письма на свой ящик? Он просто плюнет и уйдет на конкурирующий ресурс, недолго думая. Решения принимаются в течение нескольких минут, особенно, если пользователь спешит.

    Поэтому мой выбор — всё-таки проверять и выдавать пользователю сообщение о некорректном адресе СРАЗУ. Другое дело, что криворукими или сложными такие проверки не должны быть.

    p.s. кстати, статистика показывает, что пользователи могут опечатываться в адресе при вводе два раза подряд, и даже четыре.
    • +1
      > Как он узнает, что он опечатался в адресе при регистрации и не сможет зарегистрироваться?
      А как он узнает, если вы будете использовать регекспы?
  • 0
    Предлагаю проверять e-mail регуляркой, но не считать за ошибку непройденную проверку. Скажем, пользователь ввел неверный/специфичный e-mail, подсвечиваем поле и задаем вопрос «Вы уверены, что e-mail верен?» или подобный.
    • 0
      Небольшая демонстрация идеи.
      • 0
        Идея хорошая, но сразу возникает вопрос — а как сообщать? зелененьким, так никто читать не будет. Красьненьким — не поймут, что это сообщение можно проигнорировать :)
        Единственное что приходит в голову это алерт по нажатию кнопки, который будет предлагать выбор — продолжить или исправить.
        • 0
          Синеньким :-) Кроме шуток, его обычно читают, но не пугаются — это маркировка важного сообщения, но не информация о проблеме.
        • 0
          Да, всё же алерт нужен, можно его красивеньким сделать. К тому же он будет появляться только при «вероятно неверном» заполнении.
          Но можно и без алерта, можно выделить сообщения-ошибки в блок с рамочкой, сбоку такой значок красный с восклицательным знаком, а для сообщений-ворнингов блок, где сбоку такой свойственный ворнингам значек (как в Visual Studio). То есть чтобы привлекало внимание пользователя. Если уж не посмотрел — сам виноват.
  • 0
    Ага, просто пошлите письмо :) Совет хорош для небольшого стартапа.

    А что делать большим и средним компаниям, выполняющим рассылки?
    Например, читаем правила mail.ru:
    Наличие в рассылках более 5% невалидных адресов может привести к попаданию писем, отправленных с вашего домена, в папку «Спам» или даже к полной их блокировке.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.