2

パスワードとユーザー名のログインクエリを実行していますが、次のようになります

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

ユーザー名とパスワードを渡します。問題は、ユーザー名が「user」で、パスワードが「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 で始まるすべての列値が取得されることを意味します。この検索で​​大文字と小文字を区別するには、オペランドの 1 つに大文字と小文字を区別する照合またはバイナリ照合があることを確認してください。たとえば、どちらも 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 での大文字と小文字の区別については、こちらを参照してください

どちらの方法でも、おそらくユーザー名とパスワードの列にバイナリ照合を使用する必要があります。

特に:

この検索で​​大文字と小文字を区別するには、オペランドの 1 つに大文字と小文字を区別する照合またはバイナリ照合があることを確認してください。

また

列を常に大文字と小文字を区別して処理する場合は、大文字と小文字を区別する照合順序またはバイナリ照合順序で列を宣言します。セクション13.1.10「CREATE TABLE 構文」を参照してください。

また、理想的には、少なくともパスワードをソルト化およびハッシュ化する必要があります。次に、比較を行うときに、ログイン時にユーザーが提供したパスワードをソルトしてハッシュします。平文のパスワードを保存することは悪い習慣であり、避けるべきです。

于 2012-12-20T19:31:03.767 に答える