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

Posted

技术标签:

【中文标题】.net 没有字符串比较方法有效【英文标题】:.net No strings comparison methods are working 【发布时间】:2021-06-01 06:29:51 【问题描述】:

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

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)

【问题讨论】:

能分享一下if中每个变量的值吗? 我将编辑问题以添加这个,在我这样做的路上,谢谢你! 快速建议,永远不要存储纯文本密码。 password.Contains(Password) 意思是password代表的词包含在password代表的词中。这并不意味着密码包含在数据库中 首先,您是否 100% 确定字符串相等?有时那里会有不可打印的字符。它发生在我身上。 【参考方案1】:

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

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

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

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

如果在将“用户”添加到数据库之前没有完成,您还应该修剪它。

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

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

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

【讨论】:

为什么要使用 LINQ 而不是 foreach?我认为“应该”在这里没有传达正确的信息。 也许不是正确的词。它只是 LINQ 通常(正确编写时)更具可读性,并且由一些代码分析器或重构工具提供建议:-) 好的,我尝试了您发布的用户代码并使用“==”与密码进行比较,但没有成功。那么,使用 LINQ 会是这样吗? foreach (var item in UserList) var trimmedUserName = item.user.Trim(); encontrado = UserList.Any(u => trimmedUserName.Equals(User, StringComparison.CurrentCultureIgnoreCase) && item.password == Password); ^ 这工作得很好,但我不知道如何摆脱那里的 foreach 我不同意更具可读性的部分。在 LINQ 方面,正确性和可读性很可能成反比。 @SebastiánVillegas 使用 linq 您应该删除 foreach。 “UserList.Any”将为您浏览所有列表。如果不起作用,您可以在此处复制粘贴两个密码(来自数据库和用户?)【参考方案2】:

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

  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);
  

【讨论】:

由于您并不是真的想使用 dbUser,只是想知道它是否存在,我认为“.Any”运算符更合适。 @Arcord 你可能是对的,我只是假设他要对用户做其他事情。

以上是关于.net 没有字符串比较方法有效的主要内容,如果未能解决你的问题,请参考以下文章

[VB.NET Tips]再谈字符串连接之内置池

将字符串与容差进行比较

Shell 字符串比较相等、不相等方法小结

不同的字符串比较方法有啥区别[重复]

有没有更好的方法来比较一个字符串和多个字符串?

使用 EF 核心 3 将字符串与日期进行比较