JDBC - 通过数据库授权用户
JDBC - authorization users via database
我做了一个从数据库中获取数据然后授权的程序,但问题是只有最后一条记录是正确的 - 登录成功。
public class Test {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/uzytkownicy";
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) throws SQLException, ClassNotFoundException {
System.out.print("login: ");
Scanner zm1= new Scanner(System.in);
String name = zm1.next();
System.out.print("pass: ");
Scanner zm2 = new Scanner(System.in);
String password = zm2.next();
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting...");
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
Statement stmt = conn.createStatement();
String sql = "SELECT logins, passwords FROM users";
ResultSet rs = stmt.executeQuery(sql);
String databasePassword = null;
String databaseUsername = null;
while (rs.next()) {
databaseUsername = rs.getString("logins");
databasePassword = rs.getString("passwords");
}
if (name.equals(databaseUsername) && password.equals(databasePassword)) {
System.out.println("Logged in!");
}
else {
System.out.println("Bad Pass/Login");
}
rs.close();
stmt.close();
conn.close();
}
catch(SQLException se){
se.printStackTrace();
}
}
}
如果我明白你想做什么(我可能不明白),你的问题是用户名和密码的比较在 while 循环之外,所以你的:
while (rs.next())
只是循环遍历整个结果集,因此当 while 循环结束时,databaseUsername 和 databasePassword 将设置为读取的最后一行的值。
相反,将比较移动到循环内并设置一个标志(默认为 false),如果找到正确的用户名和密码则跳出循环,然后使用该标志来确定要打印的内容。
另外,您可能想阅读有关参数化查询的内容。您实际上可以让数据库为您完成所有工作,方法是使用 PreparedStatement 并进行查询:
SELECT 1 个来自 logins = ?和密码 = ?;
如果结果集包含任何内容,则用户输入了有效的用户名和密码,否则他们没有输入。查询中的问号将使用 PreparedStatement 的 set* 方法设置为名称和密码。
另一个注意事项——存储明文密码是一个可怕的想法。如果存储密码的 table 暴露(通过各种攻击或只是一个心怀不满的员工窃取它),那么每个人都拥有您所有用户的密码。哎呀!您可能会争辩说您会采取措施防止这种情况发生,但从安全角度来看,最好假设有一天 table 会受到损害,并尽一切努力确保它不会造成太大危害。
我做了一个从数据库中获取数据然后授权的程序,但问题是只有最后一条记录是正确的 - 登录成功。
public class Test {
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost:3306/uzytkownicy";
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) throws SQLException, ClassNotFoundException {
System.out.print("login: ");
Scanner zm1= new Scanner(System.in);
String name = zm1.next();
System.out.print("pass: ");
Scanner zm2 = new Scanner(System.in);
String password = zm2.next();
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("Connecting...");
Connection conn = DriverManager.getConnection(DB_URL,USER,PASS);
Statement stmt = conn.createStatement();
String sql = "SELECT logins, passwords FROM users";
ResultSet rs = stmt.executeQuery(sql);
String databasePassword = null;
String databaseUsername = null;
while (rs.next()) {
databaseUsername = rs.getString("logins");
databasePassword = rs.getString("passwords");
}
if (name.equals(databaseUsername) && password.equals(databasePassword)) {
System.out.println("Logged in!");
}
else {
System.out.println("Bad Pass/Login");
}
rs.close();
stmt.close();
conn.close();
}
catch(SQLException se){
se.printStackTrace();
}
} }
如果我明白你想做什么(我可能不明白),你的问题是用户名和密码的比较在 while 循环之外,所以你的:
while (rs.next())
只是循环遍历整个结果集,因此当 while 循环结束时,databaseUsername 和 databasePassword 将设置为读取的最后一行的值。
相反,将比较移动到循环内并设置一个标志(默认为 false),如果找到正确的用户名和密码则跳出循环,然后使用该标志来确定要打印的内容。
另外,您可能想阅读有关参数化查询的内容。您实际上可以让数据库为您完成所有工作,方法是使用 PreparedStatement 并进行查询:
SELECT 1 个来自 logins = ?和密码 = ?;
如果结果集包含任何内容,则用户输入了有效的用户名和密码,否则他们没有输入。查询中的问号将使用 PreparedStatement 的 set* 方法设置为名称和密码。
另一个注意事项——存储明文密码是一个可怕的想法。如果存储密码的 table 暴露(通过各种攻击或只是一个心怀不满的员工窃取它),那么每个人都拥有您所有用户的密码。哎呀!您可能会争辩说您会采取措施防止这种情况发生,但从安全角度来看,最好假设有一天 table 会受到损害,并尽一切努力确保它不会造成太大危害。