.net 没有字符串比较方法有效

.net No strings comparison methods are working

提问人:Sebastián Villegas 提问时间:3/3/2021 最后编辑:Sebastián Villegas 更新时间:3/3/2021 访问量:59

问:

好吧,我一直在尝试构建一个简单的登录名(没什么复杂的),一切都正常工作,但不是您需要比较数据库结果和用户输入的部分。 问题来了:

if (item.user == User && item.password == Password) {
  itExists = true;
  break;
}

item.usuario 工作正常,用户输入也正确保存,我知道这一点,因为当我尝试与此进行比较时:

if (item.user.Contains(User) && item.password.Contains(Password)) {
  itExists= true;
  break;
}

它工作“很好”,“包含”的问题在于,当用户输入一个字母时(例如,想象一下,如果在数据库中,用户/密码是 admin/admin,用户键入 a/a),它将让他登录,因为“a”包含在“admin”中

所以,我搜索了几乎所有的比较方法,我试过了这个:

// Isn't working directly. ToString(item.user) == Convert.ToString(User) && Convert.ToString(item.password) == Convert.ToString(Password)
                // Isn't working directly. item.user== User && item.password == Password
                // Isn't working directly. item.user.Equals(User) && item.password.Equals(Password)
                // Isn't working directly. String.Equals(item.user, User) && String.Equals(item.password, Password)
                // Is working, but if u write a single letter that is in the string,
                // It let u sign in. item.user.Contains(User) && item.password.Contains(Password) 

我知道这些不起作用,因为有.Contains() 它允许您使用正确的用户/密码登录,但遇到了我告诉的问题

我想知道为什么会发生这种情况,以及该怎么做。

每个变量包含:

  • item.user 是 foreach 的迭代(即带来数据库用户信息)
  • User 是用户的输入(html 表单)

完整的控制器代码在这里:

public ActionResult Index(string User, string Password) {
        var UsersList= db.Users;
        bool itExists= false;
        foreach (var item in UserList) {
            if (item.user.Contains(User) && item.password.Contains(Password)) {
               itExists= true;
               break;
}}

(我想我已经很好地解释了自己,如果我没有,对不起)

提前谢谢你:)

编辑:如果重要,我正在使用 ASP.NET (.Net Framework 4.7.2)

C# .NET 字符串 比较

评论

0赞 Arcord 3/3/2021
你能在 if 中共享每个变量的值吗?
0赞 Sebastián Villegas 3/3/2021
我会编辑问题以添加这个,在我这样做的路上,谢谢!
1赞 Trevor 3/3/2021
快速建议,永远不要存储纯文本密码。
1赞 ShanieMoonlight 3/3/2021
密码。Contains(Password) 表示是 Password 表示的单词,包含在 password 表示的单词中。这并不意味着密码包含在数据库中
0赞 insane_developer 3/3/2021
首先,你 100% 确定字符串是相等的吗?有时里面有不可打印的字符。它发生在我身上。

答:

0赞 Arcord 3/3/2021 #1

对于密码,您应该坚持使用“==”比较。用户发送的密码应该与数据库中的密码完全匹配(顺便说一下,你应该使用哈希而不是实际密码,但这不是这里的问题)。

对于用户名,您可以更灵活(例如,用户可能会使用大写字母或在后面添加空格),因此您应该注意这一点:

item.usuario.Trim().Equals(User, StringComparison.CurrentCultureIgnoreCase);

使用 Trim(),您将删除之前/之后的所有空格,并且 Equals 参数将确保比较不区分大小写。

在将“User”添加到数据库之前,如果 if 未执行任何操作,您还应该修剪它。

您还应该使用 LINQ 而不是 a for each :

var trimmedUserName = item.usuario.Trim();
var exists = UserList.Any(u => trimmedUserName.Equals(User, 
StringComparison.CurrentCultureIgnoreCase) && item.password == Password);

我相信你知道这一点,但使用“.包含“将是一个巨大的安全问题。

评论

0赞 insane_developer 3/3/2021
为什么我们应该使用 LINQ 而不是 foreach?我认为“应该”在这里没有传达正确的信息。
0赞 Arcord 3/3/2021
也许不是正确的词。它只是 LINQ 通常(如果正确编写时)更具可读性,并且一些代码分析器或重构工具建议它:-)
0赞 Sebastián Villegas 3/3/2021
好的,我尝试了您发布的用户代码并使用“==”与密码进行比较,但没有用。那么,使用 LINQ 会是这样的吗? ^ 这工作得很好,但我不明白如何摆脱那里的 foreachforeach (var item in UserList) { var trimmedUserName = item.user.Trim(); encontrado = UserList.Any(u => trimmedUserName.Equals(User, StringComparison.CurrentCultureIgnoreCase) && item.password == Password); }
0赞 insane_developer 3/3/2021
我不同意更具可读性的部分。当涉及到 LINQ 时,正确性和可读性很可能是反比相关的。
0赞 Arcord 3/3/2021
@SebastiánVillegas 使用 linq 时,您应该删除 foreach。“UserList.Any”将为您浏览所有列表。如果不起作用,您可以复制粘贴到此处的两个密码(来自数据库和用户?
0赞 ShanieMoonlight 3/3/2021 #2

我认为你应该重新排列你的索引方法。

  public ActionResult Index(string User, string Password) {
     var dbUser = _db.Users
        .FirstOrDefault(u => u.UserName == User && u.password == Password);

     if(dbUser != null)
        itExists = true;
     
     return Ok(itExists);
  }}

评论

0赞 Arcord 3/3/2021
由于您并不真正想使用 dbUser,而只是想知道它是否存在,我认为“.any“运算符更合适。
0赞 ShanieMoonlight 3/3/2021
@Arcord你可能是对的,我只是假设他会对用户做其他事情。