0

ユーザーがユーザー名とパスワードを入力すると、入力がユーザーテーブルの行と一致するかどうかを確認して認証が行われるようにしようとしています。これまでのコードは次のとおりです。ログイン ボタンをクリックしても応答しません。正しく設定する方法を教えてください。ありがとう

 private void dbConnection()
{
   try
   {
       Class.forName("com.mysql.jdbc.Driver");
       Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus");
       Statement stmt = conn.createStatement();
       String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND password = '"+this.txtPass+"'";
       ResultSet rs = stmt.executeQuery(CHECK_USER);

        while(rs.next())
        {
            String user = txtUser.getText();
            String pass = txtPass.getText();

            if(user.equals(rs.getString("username")))
            {
                if(pass.equals(rs.getString("password")))
                {
                    this.dispose();
                    new AboutTo().setVisible(true);
                }
                else JOptionPane.showMessageDialog(null, "Invalid Password");
            }
            else JOptionPane.showMessageDialog(null, "Invalid Username or Password");
        }



       stmt.close();
       rs.close();
       conn.close();
   }


   catch(SQLException | ClassNotFoundException er)
   {
       JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
   }

}
4

5 に答える 5

1

基本的に、ロジックは間違っています。

あなたがしていることはおよそこれです。

  1. ユーザーからユーザー名とパスワードを取得します。

  2. ユーザー名が提供されたユーザー名と一致し、パスワードが提供されたパスワードと一致するすべてのレコードをデータベースに問い合わせます。

  3. そのようなレコードごとに:

    1. ユーザー名が一致するかどうかをテストし、一致しない場合はダイアログを開きます。 そのユーザー名を持つレコードのみを選択したため、それは起こりません。

    2. パスワードが一致するかどうかをテストし、一致しない場合はダイアログを開きます。 そのパスワードを持つレコードのみを選択したため、それは起こりません。


あなたが本当にすべきことは次のとおりです。

  1. ユーザーからユーザー名とパスワードを取得します。

  2. ユーザー名とパスワードに一致するレコードを選択します。

  3. 一致したレコードの数がゼロの場合、メッセージを出力します。


他にもいくつか指摘しておきたいことがあります。

  • ダイアログボックスをポップアップして、ユーザー名/パスワードが間違っていることをユーザーに知らせることは重要ではありません。本当に必要なの、ログインが失敗したことをサーバー内の別の何かに伝えることです。

  • ユーザーがユーザー名またはパスワードだけを間違えた場合、どちらかが正しいという手がかりをユーザーに提供しないでください。そうすることで、「悪者」が正しい組み合わせを見つけやすくなります。

  • パスワードを平文でデータベースに保存するのは悪い習慣です。ベスト プラクティスは、シードされたパスワードのハッシュを保存し、暗号的に強力なハッシュ関数を使用することです。

于 2013-10-28T07:50:43.150 に答える
1
String CHECK_USER = "SELECT * FROM records WHERE username = '"+this.txtUser+"' AND    password = '"+this.txtPass+"'";

SQLクエリでユーザー名とパスワードを渡したので、ユーザー名とパスワードが一致する場合にのみwhileブロックに入ります...

この String CHECK_USER = "SELECT * FROM records"; のような SQL クエリを作成する必要があります。

または、このような if ブロックを使用できます if(rs.next() { //ログイン成功コード } else { //ログイン失敗 }

于 2013-10-28T07:29:43.417 に答える
1

とを呼び出すgetText()のを忘れました。txtUsertxtPass

これは、クエリを修正する方法です。

String CHECK_USER = "SELECT * FROM records WHERE username = '" + this.txtUser.getText() + "' AND password = '" + this.txtPass.getText() + "'";

生の入力テキストをクエリに連結すると、SQL インジェクションに対する脆弱性が生じることに注意してください。PreparedStatement入力テキストが適切にエスケープされるように、代わりに使用する必要があります。

以下は、これを適切に実装する方法ですが、次の点に注意する必要があります。

  • パスワードを平文で保存しています。SHA-1 などのハッシュ関数を使用する必要があります。
  • 認証ごとに、データベースへの新しい接続が行われます。おそらく、適切な接続プールを使用する必要があります。

.

private boolean authenticate() throws SQLException {
    String dbUrl = "jdbc:mysql://localhost:3306/maths_tutor";

    // This query will simply count the matching rows, instead of actually selecting
    // them. This will result in less bandwidth between your application and the server
    String query = "SELECT count(*) AS num_records FROM records WHERE username = ? AND password = ?";

    // Obtaining the username and password beforehand could perhaps make it more clear
    // and prevent errors instead of pulling the data every time you need it
    String username = txtUser.getText();
    String password = txtPass.getText();

    // The try-with-resources block will make sure the resources are closed once we are done with
    // them. More information available at
    // http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
    try (
        // Open database connection
        Connection conn = DriverManager.getConnection(dbUrl, "root", "jesus");

        // Prepare the statement
        PreparedStatement stmt = conn.prepareStatement(query)
    ) {
        // Set the username and password for the SQL statement
        stmt.setString(1, username);
        stmt.setString(2, password);

        // Execute the query in a try block, to ensure that the resources
        // will be released
        try (ResultSet rs = stmt.executeQuery()) {
            if (rs.next()) {
                // If we got 1 or more matches, this means we successfully
                // authenticated. Otherwise, we failed authentication.
                return rs.getInt("num_records") > 0;
            }
        }
    }

    // Failed authentication.
    return false;
}

// Rename this to something meaningful according to your application
private void doAuthentication() {
    try {
        if (authenticate()) {
            // Do successful authentication handling
            this.dispose();
            new AboutTo().setVisible(true);
        } else {
            // Do failed authentication handling
            JOptionPane.showMessageDialog(null, "Invalid Username or Password");
        }
    } catch(SQLException er) {
        // Do error handling
        JOptionPane.showMessageDialog(null, "Exception:\n" + er.toString());
    }
}
于 2013-10-28T07:32:27.587 に答える
-1
string query = "SELECT count(*) FROM [dbo].[login1] WHERE username='" + username.Text + "' and password='" + password.Text + "'";

SqlDataAdapter sda = new SqlDataAdapter(query, con);
DataTable dt = new DataTable();
sda.Fill(dt);

if (dt.Rows[0][0].ToString() == "1")
    {MessageBox.Show("YEAH");}
于 2015-12-10T06:41:07.247 に答える