1.用java实现登录的检查
package jdbc1;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;public class Login {public static void main(String args[]){try(Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306","root","020809");Statement statement=connection.createStatement();Scanner scanner=new Scanner(System.in);){ResultSet resultSet = statement.executeQuery("select * from accounting_ledger.user where username='"+scanner.nextLine()+"'and password='"+scanner.nextLine()+"';");while(resultSet.next()){String name = resultSet.getString(1);System.out.println(name+"login successfully!");}}catch(Exception e){e.printStackTrace();}}
}
2.注入攻击
看似没有问题,可是如果我输入的如果是以下内容呢?
Test 1111' or 1=1; --
这是因为我们实际运行的sql语句变成了
select * from user where username='Test' and pwd='1111' or 1=1; -- '
而1=1一定是对的,所以这个语句一定是正确的。我们发现,如果允许这样的数据插入,那么我们原有的SQL语句结构就遭到了破坏,使得用户能够随意登陆别人的账号。因此我们可能需要限制用户的输入来防止用户输入一些SQL语句关键字,但是关键字非常多,这并不是解决问题的最好办法。
PreparedStatement
package jdbc1;import java.sql.*;
import java.util.Scanner;public class safeLogin {public static void main(String args[]){try(Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306","root","020809");PreparedStatement statement = connection.prepareStatement("select * from user where username= ? and password=?;");Scanner scanner=new Scanner(System.in)){statement.setString(1, scanner.nextLine());statement.setString(2, scanner.nextLine());System.out.println(statement); //打印查看一下最终执行的ResultSet resultSet = statement.executeQuery();while(resultSet.next()){String name = resultSet.getString(1);System.out.println(name+"login successfully!");}}catch(Exception e){e.printStackTrace();}}
}
我们发现,我们需要提前给到PreparedStatement一个SQL语句,并且使用?
作为占位符,它会预编译一个SQL语句,通过直接将我们的内容进行替换的方式来填写数据。
而setString方法则会将读取的输入填入占位符的位置。第一个参数是传入的位置,第二个参数是传入的内容。
使用这种方式,我们之前的例子就失效了!我们来看看实际执行的SQL语句是什么:
com.mysql.cj.jdbc.ClientPreparedStatement: select * from user where username= 'Test' and pwd='123456'' or 1=1; -- ';
我们发现,我们输入的参数一旦出现'
时,会被变为转义形式\'
,而最外层有一个真正的'
来将我们输入的内容进行包裹,因此它能够有效地防止SQL注入攻击!