/** * 实现功能 * 1.需求:模拟用户登录的功能 * 2.用户描述 * 程序运行的时候,提供一个输入的接口,可以让用户按输入用户名和密码 * java程序连接数据库,提交信息,java程序收集用户信息 * java程序连接数据库验证用户名和密码是否正确 * 合法;显示登录成功 * 不合法:显示登录失败 * * 当前程序存在的问题 (很好玩) * 用户名:fdsa * 密码:fdsa' or '1'='1 * 会登录成功 * 这种现象被称为sql注入(安全隐患) * 导致sql注入的根本原因? * 用户输入的信息含有sql语句的关键字,并且这些关键字参与失去了语句的编译过程 * 导致sql语句的原意被扭曲,进而达到sql注入 */ public class JDBCTest5 { public static void main(String[] args) { //1.初始化一个界面 Map<String,String> userloginInfo = initUI(); //验证登录名和密码 boolean loginSuccess = login(userloginInfo); //最后输出结果 System.out.println(loginSuccess?"登录成功":"登录失败"); } /** * 用户登录 * @param userloginInfo * @return */ private static boolean login(Map<String, String> userloginInfo) { //打标记的意识 boolean loginSuccess = false; //单独定义变量 String loginName =userloginInfo.get("loginName"); String loginPwd =userloginInfo.get("loginPwd"); //Jdbc代码 Connection conn = null; Statement stmt =null; ResultSet rs =null; //1.注册驱动 try { Class.forName("com.mysql.cj.jdbc.Driver"); //2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC","root","root"); //3. 获取数据库操作对象 stmt = conn.createStatement(); //4.执行sql语句 String sql = "select * from t_user where loginName='"+loginName+"' and loginPwd = '"+loginPwd+"'"; rs = stmt.executeQuery(sql); //5.处理结果集 if (rs.next()){ //登陆成功 loginSuccess = true; } } catch (Exception e) { e.printStackTrace(); }finally { //6.释放资源 try { if (rs!=null){ rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (stmt!=null){ stmt.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn!=null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } return loginSuccess; } /** * 初始化用户界面 * @return 用户输入的用户名和密码等登录信息 */ private static Map<String, String> initUI() { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String loginName = sc.nextLine(); System.out.println("请输入密码:"); String loginPwd = sc.nextLine(); Map<String,String> userLoginInfo = new HashMap<>(); userLoginInfo.put("loginName",loginName); userLoginInfo.put("loginPwd",loginPwd); return userLoginInfo; } }
//2.使用PreparedStatement解决sql注入的问题
import java.sql.*; import java.util.HashMap; import java.util.Map; import java.util.Scanner; /* 1.解决sql注入问题? 只要用户提供的信息不参与sql语句的编译过程,问题就解决了 即使用户提供的信息中包含sql语句的关键字,但没有参与编译,就不起作用了 要想用户信息不参与sql语句的编译,那么必须使用preperedstatement PreparedStatement的原理是:预先对sql语句进行编译,然后再给sql语句传值 */ public class JDBCTest6 { public static void main(String[] args) { //1.初始化一个界面 Map<String,String> userloginInfo = initUI(); //验证登录名和密码 boolean loginSuccess = login(userloginInfo); //最后输出结果 System.out.println(loginSuccess?"登录成功":"登录失败"); } /** * 用户登录 * @param userloginInfo * @return */ private static boolean login(Map<String, String> userloginInfo) { //打标记的意识 boolean loginSuccess = false; //单独定义变量 String loginName =userloginInfo.get("loginName"); String loginPwd =userloginInfo.get("loginPwd"); //Jdbc代码 Connection conn = null; PreparedStatement ps =null; ResultSet rs =null; //1.注册驱动 try { Class.forName("com.mysql.cj.jdbc.Driver"); //2.获取连接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC","root","root"); //3. 获取预编译数据库操作对象 //sql语句的框子,其中一个?代表了一个占位符,一个?将来接收一个值,注意占位符不能被‘’括起来 String sql = "select * from t_user where loginName = ? and loginPwd = ?"; ps = conn.prepareStatement(sql); //给占位符?传值 ps.setString(1,loginName); ps.setString(2,loginPwd); //4.执行sql语句 rs = ps.executeQuery(); //5.处理结果集 if (rs.next()){ //登陆成功 loginSuccess = true; } } catch (Exception e) { e.printStackTrace(); }finally { //6.释放资源 try { if (rs!=null){ rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps!=null){ ps.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (conn!=null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } return loginSuccess; } /** * 初始化用户界面 * @return 用户输入的用户名和密码等登录信息 */ private static Map<String, String> initUI() { Scanner sc = new Scanner(System.in); System.out.println("请输入用户名:"); String loginName = sc.nextLine(); System.out.println("请输入密码:"); String loginPwd = sc.nextLine(); Map<String,String> userLoginInfo = new HashMap<>(); userLoginInfo.put("loginName",loginName); userLoginInfo.put("loginPwd",loginPwd); return userLoginInfo; } }