1

登録ユーザーを認証するときに、リクエストを行います。たとえば、私が見つけた1つの例:

$user = $_POST['user'];
$pw = $_POST['password'];

$sql = "SELECT user,password FROM users 
    WHERE user='$user' 
    AND password='$pw' 
    LIMIT 1";
$result = mysql_query($sql);

if (mysql_num_rows($result)){
    //we have a match!
}else{
    //no match
}

LIMIT 1では、最後に持つメリットやポイントは何でしょうか? また、user_id を選択できるのに、なぜユーザーとパスワードを選択する必要があるのでしょうか。

しませんか

SELECT user_id FROM users
WHERE user = '{$user}'
AND password = '{$pw}'

まったく同じロジスティクスですが、コードは短くなりますか?

編集: この小さな詳細について考えると、ハッカーを防ぐためのもう 1 つのチェックが見つかりました。同じ電子メールとパスワードを持つ複数のユーザーが存在してはならないため、パスワードの代わりに123文字列' OR password = '*'(または同様のロジック) を何らかの形で提供すると、クエリが危険にさらされます。次のステップを数えることができるため、制限がないことが役立ちます

if (count($result) > 1) {
   echo "we got hacked";
else 
   <proceed...>
4

5 に答える 5

4

ユーザー名とパスワードのペアごとにデータベースに 1 つの行しかないと仮定すると、LIMIT 句は、主に ORDER BY 句と組み合わせて使用​​すると、最初の一致が見つかった後に検索を中止することでパフォーマンスを向上させます。

MySQLマニュアルから:

ORDER BY で LIMIT row_count を使用する場合、MySQL は、結果全体をソートするのではなく、ソートされた結果の最初の row_count 行が見つかるとすぐにソートを終了します。インデックスを使用して順序付けを行う場合、これは非常に高速です。

于 2012-04-09T13:29:09.177 に答える
1

ほとんどの場合、一意のuser列があるため、LIMIT 1必須ではありません。いずれにせよ、複数の行はありません。

この場合、それは装飾的な要素である可能性があります。つまり、コードを読み取るプログラマーに、クエリが 1 行しか返さないことを伝える自己説明型の構文です。

あなたの質問は別として、パスワード暗号化などを使用することを強くお勧めしますMD5()。単純なパスワードを保存する方法を教えるチュートリアルは、最適なものではありません...

于 2012-04-09T13:31:23.840 に答える
1

「 SQL インジェクション: PHP / MySQL のセキュリティ上の欠陥を防ぐ方法」を読んで、適切な対策を講じないとログインが役に立たないことを確認してください。

他のすべては、上記のはるかに賢明なポスターによって答えられました.

于 2012-04-09T13:39:20.323 に答える
0

ほとんどの場合、テーブルには一意のユーザー名が保持されるため、常に 1 行または 0 行が返されます。そして、コードに関する限り、違いはありません。複数の行が返された場合でも、返された行の数ではなく、行の存在のみをチェックしているため、コードは引き続き機能します (ただし、実際にログインしているユーザーがわからないため、これは正しくありません)。 .

基本的に、WHERE の条件を満たす最初の行が見つかった後、MySQL にテーブルの検索を停止するように指示するだけです。場合によっては、これでも冗長になる可能性があります (たとえば、「user」フィールドに UNIQUE インデックスがある場合)。

あなたの質問に関係のないもう 1 つのこと: このコードを学習以外の目的で使用しないでください。セキュリティホールだらけです。このコードを本番環境に配置する前に、「SQL インジェクション」と「パスワードを安全に保存する」ことについて Google に問い合わせてください。

于 2012-04-09T13:30:59.837 に答える
-1

まず、注入から文字列をサニタイズする必要があります:

class main{
public function sanitize($str,$remove_nl=true)
        {
            stripslashes($str);

            if($remove_nl)
            {
                $injections = array('/(\n+)/i',
                    '/(\r+)/i',
                    '/(\t+)/i',
                    '/(%0A+)/i',
                    '/(%0D+)/i',
                    '/(%08+)/i',
                    '/(%09+)/i'
                    );
                $str = preg_replace($injections,'',$str);
            }

            return $str;
        }
}

次のあなたのコード:

$main_class = new main();

$user = $main_class->sanitize(trim($_POST['user']));
$pw = $main_class->sanitize(trim($_POST['password']));

$sql = "SELECT * FROM `users` WHERE `user`='".$user."' AND `password`='".$pw."' LIMIT 0,1";
$result = mysql_query($sql) or die(mysql_error());
$count = mysql_num_rows($result);

if($count > 0){
    //we have a match!
}else{
    //no match
}
于 2012-04-09T13:34:40.927 に答える