Я работаю над проектом MERN, и при входе в систему я нахожу этого пользователя следующим образом:
User.findOne ({имя пользователя: req.body.username}).exec (функция (ошибка, пользователь) { если (пользователь) { Строки кода.... });
Представьте, что мое имя пользователя — Имран, сохраненное в Db, и отправьте имя пользователя в приведенном выше коде как .
Дело 1: req.body.username = Имран Пользователь найден 1
Случай 2: req.body.username = имран Пользователь найден 0
Случай 3: req.body.username = imRan Пользователь найден 0
Если я использую регулярное выражение, чтобы найти такое имя пользователя...
User.findOne({имя пользователя: {$regex: имя пользователя, $options: "i"}})
Он найдет пользователя во всех вышеперечисленных случаях, но если я наберу imr, а не Imran, imran или imRan с заданным паролем, он снова войдет в систему этого пользователя, что неверно! Так что я надеюсь. Если бы кто-нибудь мог помочь мне в этом вопросе! Это будет здорово!





Вы хотели бы нормализовать данные при сохранении, вызвав username.toLowerCase() (или toUpperCase()). Затем, когда вы выполняете запрос, вы вызываете User.findOne({username:req.body.username.toLowerCase()})
Я поддерживаю это предложение. Как правило, плохая практика не дезинфицировать пользовательский ввод и хранить его непосредственно в вашей базе данных. Если вы не собираетесь разрешать использование имени пользователя в смешанном регистре, вам следует дезинфицировать ваши входные данные.
Я не полностью согласен. Что, если оболочка действительно важна? Нравится по именам? Почему вы сохраняете данные в нижнем регистре?
@JuanManuelHaedo, вы определенно захотите нормализовать данные таким образом, только если регистр не важен. Например, адреса электронной почты нечувствительны к регистру. Для полей, чувствительных к регистру, вам нужно будет использовать нечувствительный к регистру поиск $regex, или у вас может быть дублированное поле, которое нормализовано ко всем строчным буквам для поиска без учета регистра.
Я бы рекомендовал хранить имена пользователей в нижнем регистре, по крайней мере, вы хотите различать имена пользователей в нижнем и верхнем регистре, если это так, Imran и imran — это два разных пользователя. В любом случае, чтобы соответствовать запросу без учета регистра, вы можете попробовать следующее:
User.findOne({username: /^imran$/i})
Или
User.findOne({username: {$regex: '^imran$', $options: 'i'}})
В последнем вы передаете значение регулярного выражения в виде строки, чтобы вы могли включить переменную между ^ и $, надеюсь, это поможет.
Как я могу дать динамическое значение, отличное от Имрана! Я делаю так .. User.findOne( {username: /^username$/I } )... Но не работает
попробуйте с: User.findOne({username: {$regex: '^imran$', $options: 'i'}}), я отредактирую
Вы делаете его динамическим, используя переменную User.findOne({username: {$regex: new RegExp(`^${username}$`, 'i')}})
Обратите внимание, что [email protected] и [email protected] совпадают при использовании \b\b или ^$, поскольку точка интерпретируется как любая строка.
Спасибо всем за помощь ! Я нашел решение, которое работает для меня. User.findOne({имя пользователя: новое регулярное выражение("\b" + имя пользователя + "\b", "i") } .... Это будет соответствовать строке имени пользователя, будь то в нижнем регистре или в верхнем регистре. Надеюсь, это поможет вам :)
Согласно моему комментарию выше, это не сработает по той же причине (мешает регулярное выражение внутри строки).
В моем случае использования (электронные письма) у меня были проблемы, поскольку другие ответы соответствовали данным, которые не были экранированы.
Например, при использовании неэкранированных строк расширение . (точка) в электронных письмах будет использоваться для соответствия любому символу, и, таким образом, [email protected] и [email protected] будут совпадать при поиске [email protected].
Мое решение для этого состояло в том, чтобы сначала избежать строки. Я также рекомендую дезинфицировать ваши входные данные, но если вы не можете, убедитесь, что вы избегаете своих строк.
if (email) {
email = _.escapeRegExp(email.toLowerCase());
let filter = { email: { $regex: new RegExp(`^${email}$`, 'i') } };
}
Приведенное выше решение требует лодаш, но вместо этого его можно выполнить с помощью метода замены строки.
Не могли бы вы объяснить, что вы хотите сделать с полем имени пользователя? Насколько я знаю, mongodb проверит ваше имя пользователя только для случая 1, и это должен быть единственный случай. Если вы собираетесь выполнять автозаполнение или любые другие действия, то лучше сделать это на верхних слоях, а не в базе данных, чтобы минимизировать нагрузку на производительность.