Любой современный поставщик услуг электронной почты рассматривает электронные письма как регистронезависимые, а это означает, что в моем приложении я должен разрешить пользователям входить в систему как с помощью [email protected]
, так и [email protected]
.
Что касается символов от A до Z, это легко реализовать, поскольку я всегда могу преобразовать ввод в нижний регистр.
Однако если адрес электронной почты пользователя содержит другие символы, например немецкий ß, который преобразуется в SS в верхнем регистре (который преобразуется обратно в ss в нижнем регистре), или другие международные символы, для которых могут действовать специальные правила преобразования нижнего и верхнего регистра, тогда подвергаюсь ли я теперь риску того, что пользователи не смогут войти в систему, если они введут адрес электронной почты в другом «регистре», отличном от того, в котором они изначально зарегистрировались?
Тогда было бы лучше использовать toLocaleLowerCase() в моем сценарии? Или мне следует преобразовать только символы от A до Z и оставить остальные в том случае, если они были указаны? Или что мне делать в этом случае?
Моя текущая реализация просто (псевдокод):
// when storing the email on my DB
db.user.save({ email: inputEmail.toLowerCase(), ... })
// when finding the user to authenticate
db.user.find("email", inputEmail.toLowerCase())
Какую базу данных вы используете. Выполняет ли он автоматически поиск без учета регистра?
Я использую MongoDB @phuzi
Сделайте это для всех языков. Пользователи могут каждый раз пробовать разные способы. Вы можете использовать библиотеку unorm
Почему вы хотите изменить способ добавления пользователем своего почтового адреса? На мой взгляд, было бы странно, если бы я добавил [email protected], а вы конвертировали бы его во что-нибудь еще, чем я не пользовался.
@Nico OTOH, также было бы странно, если бы один пользователь с одним адресом электронной почты мог зарегистрировать несколько учетных записей, просто по-разному написав свой адрес электронной почты с заглавной буквы.
@NicoHaase, потому что если вы попытаетесь войти в систему, используя [email protected] после регистрации на [email protected], вам в конечном итоге сообщат, что с этим адресом электронной почты не зарегистрирована ни одна учетная запись, что не соответствует тому, как современные поставщики услуг электронной почты обрабатывают это
Примечание: рекомендуется вообще рассмотреть эту проблему, а не просто притворяться, что все адреса электронной почты содержат только какое-то произвольно выбранное подмножество ASCII.
@deceze Я читаю комментарий Нико больше, чем было бы странно, если бы адрес отображался в пользовательском интерфейсе иначе, чем он был введен изначально и т. д. - тем более для всего, что попадает в лагерь типа «ExpertsExchange», где потеря капиталов приводит к дополнительным путаница...
Я думаю, было бы неплохо сравнить введенный адрес в строчной форме с строчной формой адреса в базе данных, чтобы избежать входа в разные учетные записи (уникальные индексы AFAIK MySQL могут обойти это, так что вы не можете вводить одна и та же строка с разными регистрами в нескольких строках). Но сохранение любой другой строки, кроме той, которую я ввел, заставило бы меня задуматься.
Имейте в виду: для нас, технических специалистов, может быть очевидно, что оба адреса технически равны. Кто-то менее твердый, например ваша бабушка, возможно, не поймет, что ваша форма просто не принимает ее почтовый адрес, как она использовала его в течение многих лет.
В чем именно здесь проблема? Если пользователь указал один и тот же адрес электронной почты для регистрации и входа в систему, то .toLowerCase()
выдаст одну и ту же строку. И почему преобразование в верхний, а затем в нижний вид не приводит к появлению исходных символов и является проблемой? В вашем примере вы не конвертируете в верхний регистр, и я не вижу в этом необходимости.
Кроме того, некоторые провайдеры электронной почты могут иметь адреса электронной почты в нескольких формах. т. е. [email protected]
, [email protected]
, [email protected]
и [email protected]
— это адреса электронной почты из одной и той же учетной записи Gmail.
@gre_gor Я использовал только немецкий ß в качестве примера, так как я немного знаю немецкий и не знаю другого конкретного примера, но, конечно, есть десятки тысяч символов, о которых я понятия не имею, как они будут вести себя, например, как китайские или арабские символы
Лучшим примером проблемы может быть использование верхнего регистра для сопоставления без учета регистра. В этом случае «Strauß@example.com» и «[email protected]» будут совпадать, но почтовый сервер может считать их разными учетными записями.
Ну, вы можете либо использовать storedEmail.toLowerCase() === inputEmail.toLowercase()
во время регистрации/входа в систему, либо при каждом вводе символа вы можете мгновенно переводить его в нижний регистр (например, <input value = {inputEmail.toLowerCase()} onChange = {setInputEmail} />
. Для нескольких языков вы можете использовать toLocaleLowerCase()
, я никогда не использовал его, но он преобразует строку в строчные буквы, используя текущая локаль, основанная на языковых настройках браузера
«будут совпадать, но почтовый сервер может считать их разными учетными записями» — вы никогда не узнаете, какие именно произвольные почтовые серверы будут считать одним и тем же почтовым ящиком или нет. «Это означает, что в моем приложении я должен разрешить пользователям входить в обе системы» - нет. Вам нужно только разрешить вход под тем же адресом, который использовался при регистрации. Храните это в своей базе данных, а не что-то еще. Это также адрес, который вам нужно будет использовать при отправке электронного письма — не меняйте регистр!
Любой современный поставщик услуг электронной почты обрабатывает электронные письма без учета регистра.
Да.
Хотя, если вы использовали верхний регистр для сопоставления без учета регистра,
Strauß@example.com
и[email protected]
будут совпадать, но почтовый сервер может считать их разными учетными записями.
Вы никогда не узнаете, что именно произвольные почтовые серверы будут считать одним и тем же почтовым ящиком или нет.
… это означает, что в моем приложении я должен разрешить пользователям входить в обе
Нет. Вам нужно разрешить вход только под тем же адресом, который использовался при регистрации. Храните это в своей базе данных, а не что-то еще. Это также адрес, который вам нужно будет использовать при отправке электронного письма — не меняйте регистр! Чтобы ответить на главный вопрос, никогда не безопасно преобразовывать адрес электронной почты в другой регистр, независимо от того, делаете ли вы это только для символов [a-z] или нет.
Однако, независимо от адреса электронной почты, хранящегося в профиле пользователя, для удобства вы можете разрешить вход в систему, когда пользователь вводит достаточно похожий адрес электронной почты. Здесь вы можете создавать произвольные правила, при условии, что «Штраусс» войдет в реальную учетную запись Strauß@example.com
. Конечно, это означает, что вам также придется запретить пользователям создавать учетные записи с похожими адресами электронной почты, но вы в безопасности, если следуете одним и тем же (произвольным) правилам нормализации для проверки уникальности. Обратите внимание, что также полезно предотвратить гомоглифические атаки, особенно если адрес электронной почты отображается публично или любому другому пользователю.
Хорошо, если я правильно понимаю, мне всегда следует хранить электронное письмо в том виде, в котором оно было предоставлено. Затем, как во время регистрации, так и во время входа в систему, я могу установить свои собственные правила относительно того, что представляет собой уникальность, при условии, что в обоих сценариях применяются одни и те же правила?
Да, я думал, что правила могут быть другими. Для регистрации второй учетной записи соответствие может быть менее строгим (т. е. рассматривать больше значений как аналогичные существующим учетным записям), чем для входа в систему. Правила должны предотвратить получение логина, который будет соответствовать нескольким учетным записям.
Полная касательная, но следует учитывать параметры сортировки, используемые в самой базе данных, тогда вашему коду в каждой точке взаимодействия с базой данных не придется об этом беспокоиться.