2013-10-28 21 views
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()); 
    } 

} 
+0

什麼異常你得到? –

+4

你爲什麼要檢查數據庫的SQL是否工作?如果你得到一個結果,有一場比賽,你不需要檢查它。順便說一句如果你沒有得到一個匹配,它不會返回一個不匹配的隨機記錄,它不會返回任何內容,所以你應該使用'if(rs.next()){ok} else {not ok}' –

+0

這段代碼只是將給定的用戶名和密碼與DB數據進行比較。單擊登錄按鈕時調用此方法的代碼在哪裏? – SudoRahul

回答

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

所以進去,而塊只有當用戶名和密碼將匹配...

你應該讓SQL querylike這 字符串CHECK_USER你已經通過在SQL查詢&用戶名密碼=「選擇*從記錄」;

,或者您可以使用,如果塊這樣 如果(rs.next(){ // 登錄全成代碼 } 其他 {// 登錄失敗 }

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()); 
    } 
} 
1

基本上,邏輯錯了。

你在做什麼大約是這樣。

  1. 從用戶處獲取用戶名和密碼。

  2. 向數據庫詢問用戶名與所提供的用戶名匹配的所有記錄,並且密碼與提供的密碼相匹配。

  3. 對於每一次這樣的記錄:如果用戶名相匹配,並打開一個對話框,如果它不匹配

    1. 測試。 這不會發生......,因爲您只選擇了具有該用戶名的記錄。

    2. 測試密碼是否匹配,如果不匹配則打開對話框。 這不會發生......,因爲您只選擇了具有該密碼的記錄。


你真正應該做的是:

  1. 獲取用戶名和用戶密碼。

  2. 選擇與用戶名和密碼匹配的記錄。

  3. 如果數字您匹配的記錄爲零,則打印一條消息。


我還要指出的一些其他的事情:

  • 彈出一個對話框,告訴用戶他的用戶名/密碼是錯的是跑題。 真的需要做的是在服務器上告訴其他人登錄失敗。

  • 當用戶剛得到的用戶名或只是密碼不正確,你不應該給他任何線索,一個是正確的。這樣做可以讓「壞人」更容易找出正確的組合。

  • 在數據庫中清楚地存儲密碼是不好的做法。最佳做法是存儲密碼的種子哈希...並使用密碼強大的哈希函數。

0

可能出現的錯誤將接近該行

Class.forName("com.mysql.jdbc.Driver"); 
     Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maths_tutor", "root", "jesus"); 

首先確保你已經設置了類路徑,並添加MySQL驅動的項目
第二我將在下面代替上面,事實上你爲什麼要讓事情變得複雜?!

java.sql.Driver _dr=new com.mysql.jdbc.Driver(); 
java.util.Properties _pr=new java.util.Properties(); 
_pr.setProperty("user","root"); 
_pr.setProperty("password","jesus"); 
Connection conn = _dr.connect("jdbc:mysql://localhost:3306/maths_tutor", _pr); 

和最後一件事是提防有關使用此類似的代碼

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

所以這裏的系統準備injection
所以最好的方法就是像這樣使用參數。

String CHECK_USER = "SELECT * FROM records WHERE username = ? AND password = ?";//this will avoid sql injection 
java.sql.PreparedStatement _st=conn.prepareStatement(CHECK_USER); 
_st.setString(1, this.txtUser); 
_st.setString(1, this.txtPass); 



編輯:
順便說一下,有沒有需要遍歷結果集!只需調用next()方法,如果它返回true,則表示用戶已輸入正確的用戶/密碼,否則返回。

ResultSet rs = stmt.executeQuery(CHECK_USER); 
if(rs.next()){/*user exist*/ 
this.dispose(); 
new AboutTo().setVisible(true); } 
else{ 
JOptionPane.showMessageDialog(null, "Invalid Username or Password"); 
} 
-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");}