我正在使用JDBC来检查数据库中的用户名和密码,以授予我gui的登录访问权限,但是当我尝试测试JDBC是否正在运行时,如果输入了错误的用户名和密码,则无法阻止访问..
答案 0 :(得分: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);
}
答案 1 :(得分: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
}
答案 2 :(得分:0)
我提供密码=“”时会看到一个问题,并且在这种情况下没有找到记录,以下代码将返回true
if (orPass.equals(password)) // when password =""
答案 3 :(得分:0)
这是不是良好的JDBC代码。我希望您不打算在生产中使用此代码。
以下是其中许多错误中的一小部分:
答案 4 :(得分:0)
一些侧面观察:
1:下面的评论不正确,该功能没有(或不应该)启动应用程序。它应该只验证用户名和密码并返回true / false。 启动应用程序应该在它自己的函数中(函数应该做一件事)。
//启动应用程序
public static boolean checkLogin(String username,String password)
2:你应该使用try / catch / finally块来获取连接,preparedStatement和resultSet。然后在finally块中以相反的顺序关闭它们(先检查空值),通常都在同一个函数中。
3:应该使用连接池(dataSource),并且应用程序的dataSource应该在运行的应用程序的持续时间内实现一次。使用池,应尽快获取,使用和关闭(返回池)连接。