2

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

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

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

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

3 回答 3

4

MySQL 文档

简单的比较操作(>=、>、=、<、<=、排序和分组)基于每个字符的“排序值”。具有相同排序值的字符被视为相同字符。例如,如果“e”和“é”在给定的排序规则中具有相同的排序值,则它们比较相等。

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

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

于 2012-12-20T19:29:35.173 回答
2

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

默认 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

于 2012-12-20T19:30:24.863 回答
2

你使用什么排序规则?有关 MySQL 中区分大小写的信息,请参见此处

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

尤其:

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

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

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

于 2012-12-20T19:31:03.767 回答