我试图为一个连接到MYSQL的图书馆管理系统写一个登录()和连接()函数。当我试图从数据库中检索 "personnummer "和 "password "时,它返回rs.Next() == false。表已填充,查询返回 "数据库连接"。谁能帮我找出我做错了什么? 谢谢你的帮助
public class main {
public static void login() {
//UI layer has been removed
loginButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String personnummer = F_personnummer.getText();
char[] password = F_password.getPassword();
if(personnummer.equals("")){
JOptionPane.showMessageDialog(null,"Please enter personnummer (YYMMDDXXXX)");
} else if (password.equals("")){
JOptionPane.showMessageDialog(null,"Please enter password");
} else {
try {
Connection connection=connect();
Statement stmt = connection.createStatement();
stmt.executeUpdate("USE library");
PreparedStatement loginQuery = connection.prepareStatement("SELECT * FROM library.users WHERE personnummer = " + "'" + personnummer + "'" + " AND password ='" + password + "'", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = loginQuery.executeQuery();
if(rs.next()==false) {
JOptionPane.showMessageDialog(null,
} else {
jframe.dispose();
rs.beforeFirst();
while(rs.next()) {
if(personnummer.equals("admin") & password.equals("admin")) {
adminMenu();
} else {
userMenu(personnummer);
}
} // end while ()
} // end else ()
} // end try ()
catch (Exception exception) {
exception.printStackTrace();
}
}
}
});
// UI layer has been removed
}
public static Connection connect() throws Exception{
try{
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/library?useTimezone=true&serverTimezone=UTC";
String username = "root";
String password = "root";
Class.forName(driver);
Connection connection = DriverManager.getConnection(url,username,password);
System.out.println("Connected to database");
return connection;
}
catch (Exception exception) {
System.out.println(exception);
}
return null;
}
这个代码是一个安全漏洞,例如,我可以输入这个作为密码。whatever'; DROP TABLE library.users; --
- 然后在登录表的密码框里输入这个密码 你的数据库表就会灰飞烟灭。解决办法是使用 PreparedStatement
SQL查询必须始终是一个单一的长字符串常量,你绝对不能把用户的输入混合进去。你已经有了 PreparedStatement
在那里 - 只需用问号代替所有这些字符串。
PreparedStatement loginQuery = connection.prepareStatement("SELECT * FROM library.users WHERE personnummer = ? AND password = ?", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
loginQuery.setString(1, personnummer);
loginQuery.setString(2, password);
你应该使用bcrypt、scrypt、pbkdf2或其他密码哈希算法;这对你的用户来说是不安全的(你的笔记本与db的克隆最终流落街头,现在你所有用户的密码都流落街头。用户往往会重复使用密码。一般整个行业,特别是GDPR等各种法律,把责任完全推给你。包括与高额的罚款。不要打破行业标准--使用密码哈希器。
你正在将'password'变量连接成一个字符串。这将调用变量的toString。变量是一个char数组,并不能像你想象的那样调用toString。 你的查询最后变成了。SELECT * FROM whatever WHERE password = '[C@1234567'
- 试试吧 打印那个字符串。
ps.setString(2, new String(password))
.