2013-09-27 89 views
0

我正在使用JDBC檢查數據庫中的用戶名和密碼,以授予對我的gui的登錄訪問權限,但是當我嘗試測試JDBC時在輸入錯誤的用戶名和密碼時工作不阻止訪問。使用JDBC爲gui實現用戶名和密碼檢查,但

+0

吞嚥異常不是一個好習慣。 –

+0

這段代碼看起來像預期的那樣工作(除了你可以使用'if(rs.next()'而不是'while')。可能你的問題是你如何向用戶展示你的GUI。 –

+0

@LuiggiMendoza更新了代碼gui。 – Hayde

回答

0

如果輸入非現有用戶和空密碼,則您的方法將返回true。所以在這種情況下,它不會阻止訪問。爲了避免這種情況,你需要驗證用戶是否也存在。

這裏是一個例子。你可能不想這樣做,但你應該明白這一點。

if (rs.next() && password.equals(rs.getString("password"))) { 
    // do something 
    return true; 
} else { 
    //do something 
} 

此外,當您從調用checkLogin方法ActionListener你不檢查返回值,這樣你就不會真正確認任何事情。你可以做這樣的事情

if (usernamecheck.checkLogin(jtfUsername.getText(), jtfPassword.getText())) { 
    // User validated 
} else { 
    // Not validated 
} 
+0

所以增加'orgUname.equals(用戶名)',如果語句修復這個問題? – Hayde

+0

其實有人可以登錄用空的用戶名和空密碼不好 – ellak

+0

嗯我很困惑如何解決這個問題... – Hayde

0

時提供的密碼,我可以看到一個問題=「」,並有將沒有記錄在這種情況下,找到下面的代碼將返回true

if (orPass.equals(password)) // when password ="" 
0

這是不是不錯的JDBC代碼。我希望你不打算在生產中使用這些代碼。

這裏只是少數人的很多東西都是不對的地方:

  • 硬編碼驅動程序,URL和憑據。應該在連接池中設置,在應用程序外部。
  • 空的catch塊。
  • 不關閉Connection,Statement或ResultSet。
  • 沒有應用程序應該有權訪問數據庫。您應該創建一個應用程序ID並僅授予完成該任務所需的權限。
2

這裏有一些建議:

不存儲密碼的數據庫。存儲它的MD5哈希值,然後讓您的Java代碼或Mysql函數將用戶的密碼輸入文本轉換爲MD5哈希值,然後將其與您的person表中存儲的值進行比較。

實施例使用Java做散列:

person表:

+----+------------+----------------------------------+ 
| id | username | pwhash       | 
+----+------------+----------------------------------+ 
| 1 | bob  | 9ae4f6963062ba8c77db69aa1f821310 | 
| 2 | ryan  | 3f6af9632621a8ce7d00aa122e2d1310 | 
+----+------------+----------------------------------+ 

Java代碼:

import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

.... 

String username = ... // from UI input 
String plaintext_password = ... // from UI input 

String pwhash_from_passwd = makePwHash(username, plaintext_password); 

String pwhash_from_db = ... // SELECT pwhash FROM person WHERE userName=? 

if (pwhash_from_db.equals(pw_hash_from_passwd)) { 
    // user is authenticated 
} else { 
    // invalid username or password 
} 

... 



protected static String makePwHash(String username, String plaintext_password) { 
    MessageDigest mdigest=null; 
    try { 
     mdigest = MessageDigest.getInstance("MD5"); 
     String dbs = username + plaintext_password; 
     byte mdbytes[] = mdigest.digest(dbs.getBytes()); 
     return toHexString(mdbytes); 
    } catch (NoSuchAlgorithmException e) { } 
    return null; 
} 



private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 

/** 
* convert an array of bytes to an hexadecimal string 
* @return a string (length = 2 * b.length) 
* @param b bytes array to convert to a hexadecimal string 
*/ 
public static String toHexString(byte b[]) { 
    int pos = 0; 
    char[] c = new char[b.length*2]; 
    for (int i=0; i< b.length; i++) { 
     c[pos++] = toHex[(b[i] >> 4) & 0x0F]; 
     c[pos++] = toHex[b[i] & 0x0f]; 
    } 
    return new String(c); 
} 
+0

阿門,兄弟。 +1。值得一提的是醃製。 – duffymo

+0

感謝您的支持,我可能會在解決當前問題後執行此操作。 – Hayde

0

幾個側觀察:

1:下面的評論是不正確的,該功能不(或不應該)啓動應用程序上。它只應驗證用戶名和密碼並返回true/false。 啓動應用程序應該有其自己的功能(一個功能應該做一件事)。

//啓動應用程序

公共靜態布爾checkLogin(用戶名字符串,字符串密碼)

2:你應該使用一個try/catch/finally塊來獲取連接,preparedStatement時,和ResultSet。然後在finally塊中以相反的順序關閉它們(首先檢查null),通常都在同一個函數中。

3:應該使用連接池(dataSource),並且應用程序的數據源應該在運行應用程序期間執行一次。使用池,應該儘可能快地獲得,使用和關閉(返回池)連接。