【问题标题】:MySQL query ignoring capitalizationMySQL查询忽略大小写
【发布时间】:2012-12-08 09:05:53
【问题描述】:

我正在做密码和用户名登录查询,看起来像这样

$query = "SELECT id FROM users WHERE username = ? AND password = ?";

我输入了我的用户名和密码。问题是说我有一个用户名“用户”和他们的密码“密码”。当我在字段中输入“用户”和“密码”时,它仍然返回结果。所以这使得资本毫无用处。难道我做错了什么?有没有更好的方法来解决这个问题?用户名的大写问题是相同的。当我想要一个精确的字符串匹配时,它就像是在做一个模式匹配。我也尝试过二进制,希望它可能会改变它但结果相同。

$stmt = $this->db->prepare($query);
$stmt->bind_param("ss", $user, $pass);
$stmt->execute();

【问题讨论】:

  • 如何将变量传递给这个查询?你的桌子是什么类型的?
  • 密码应该被散列(和加盐),在这种情况下,散列大小写无关紧要,但散列只能由正确大小写的密码生成。
  • users的排序规则是什么?
  • 您是否有任何关于如何正确地散列和加盐密码的链接或信息?我知道它是什么我只是不知道该怎么做。
  • 您指的是我的密码和用户名列的数据类型吗?如果是这样,它们是 varchar

标签: php mysql


【解决方案1】:

来自MySQL documentation

简单的比较操作(>=、>、=、

默认字符集和排序规则是 latin1 和 latin1_swedish_ci,因此默认情况下非二进制字符串比较不区分大小写。这意味着如果您使用 col_name LIKE 'a%' 进行搜索,您将获得所有以 A 或 a 开头的列值。要使此搜索区分大小写,请确保其中一个操作数具有区分大小写或二进制排序规则。例如,如果您要比较的列和字符串都具有 latin1 字符集,则可以使用 COLLATE 运算符使任一操作数具有 latin1_general_cs 或 latin1_bin 排序规则:

您应该将表或列的排序规则更改为区分大小写或使用二进制排序规则。

【讨论】:

    【解决方案2】:

    您使用什么排序规则? see here for information on case sensitivity in MySQL

    无论哪种方式,您都应该对用户名和密码列使用二进制排序规则。

    值得注意的是:

    要使此搜索区分大小写,请确保其中一个操作数具有区分大小写或二进制排序规则。

    还有

    如果您希望始终以区分大小写的方式处理列,请使用区分大小写或二进制排序规则声明它。请参阅第 13.1.10 节,“CREATE TABLE 语法”。

    此外,理想情况下,您应该至少对密码进行加盐和散列处理。然后,在进行比较时,您可以在登录时对用户提供的密码进行加盐和哈希处理。存储明文密码是不好的做法,应该避免。

    【讨论】:

      【解决方案3】:

      这是一个典型的排序规则问题。 默认排序规则比较不区分大小写。您应该使用二进制排序规则进行比较。

      默认 utf8 排序规则

      mysql> SELECT 'password' COLLATE utf8_unicode_ci = 'PASSWORD' COLLATE utf8_unicode_ci;
      +-------------------------------------------------------------------------+
      | 'password' COLLATE utf8_unicode_ci = 'PASSWORD' COLLATE utf8_unicode_ci |
      +-------------------------------------------------------------------------+
      |                                                                       1 |
      +-------------------------------------------------------------------------+
      1 row in set (0.00 sec)
      

      utf8 二进制排序规则

      mysql> SELECT 'password' COLLATE utf8_bin = 'PASSWORD' COLLATE utf8_bin;
      +-----------------------------------------------------------+
      | 'password' COLLATE utf8_bin = 'PASSWORD' COLLATE utf8_bin |
      +-----------------------------------------------------------+
      |                                                         0 |
      +-----------------------------------------------------------+
      1 row in set (0.00 sec)
      
      mysql> SELECT 'password' COLLATE utf8_unicode_ci = 'password' COLLATE utf8_unicode_ci;
      +-------------------------------------------------------------------------+
      | 'password' COLLATE utf8_unicode_ci = 'password' COLLATE utf8_unicode_ci |
      +-------------------------------------------------------------------------+
      |                                                                       1 |
      +-------------------------------------------------------------------------+
      1 row in set (0.00 sec)
      

      将您的查询更改为

      $query = "SELECT id FROM users WHERE username = ? AND password COLLATE utf8_bin = ?";
      

      在此处阅读有关排序规则的更多信息:

      https://dev.mysql.com/doc/refman/5.5/en/charset-general.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-10
        • 1970-01-01
        • 2020-04-25
        • 2011-03-23
        • 1970-01-01
        • 2010-11-05
        • 2011-06-22
        • 1970-01-01
        相关资源
        最近更新 更多