Java-JDBC-PreparedStatement和SQL注入

Java-JDBC-PreparedStatement和SQL注入


目录




内容

1、登录案例

  • 需求:输入用户名和密码,如果用户名和密码同数据库中存储的用户名和密码相同,则运行登录,否则不允许登录

  • 步骤:

    • 创建login表

      • username字段

      • password字段

          create table login(
          id int primary key auto_increment,
          username varchar(20) not null,
          password varchar(100) not null
          );
        
    • 插入测试数据

        insert into login(username, password) values ('zhangsan', 'a123'), 
        ('lishi', '3f2f3');
      
    • 图示1-1:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pE2TSm8B-1592487282529)(./images/login.png)]

    • 编写登录逻辑

        package cn.gaogzhen.jdbc;
      
        import java.sql.Connection;
        import java.sql.ResultSet;
        import java.sql.SQLException;
        import java.sql.Statement;
        import java.util.ArrayList;
        import java.util.Date;
        import java.util.List;
        import java.util.Scanner;
      
        import cn.gaogzhen.domain.Emp;
        import cn.gaogzhen.util.JDBCUtils;
      
        public class JDBCDemo7 {
        	public static void main(String[] args) throws SQLException {
        		Scanner sc = new Scanner(System.in);
        		System.out.println("请输入用户名:");
        		String username = sc.nextLine().trim();
        		System.out.println("请输入密码:");
        		String password = sc.nextLine().trim();
        		String res = login(username, password)? "登录成功": "登录失败";
        		System.out.println(res);
        	 }
      
        	public static boolean login(String username, String password) throws SQLException {
        		if(username == null || password == null) return false;
        		Connection conn = JDBCUtils.getConnection();
        		String sql = "select * from login where username = '" + username +"' and password = '" + password + "'";
        		Statement stmt = conn.createStatement();
        		ResultSet rs = stmt.executeQuery(sql);
        		boolean flag = rs.next();
        		JDBCUtils.close(rs, stmt, conn);
        		return flag;
        	}
        }
      
    • 测试结果:

        // 成功
        请输入用户名:
        zhangsan
        请输入密码:
        a123
        登录成功
        // 失败
        请输入用户名:
        fewf
        请输入密码:
        fwfe
        登录失败
      
  • 注意:JDBCUtils类为上一篇JDBCUtils工具类博文中编写的工具类

2、SQL注入

  在#1登录案例中,如何密码输入

as' or '1' = '1# 

用户名随意,试一下会发生什么?
测试结果:

请输入用户名:
fasdfa
请输入密码:
sfas' or '1'='1
登录成功

  这就是SQL注入问题,关于SQL注入的详情,有兴趣的小伙伴可自行查阅相关文档。那么这里怎么解决SQL注入问题呢?这就是需要用到下面要介绍的PreparedStatement对象。

3、PreparedStatement

  • 表示预编译的SQL语句的对象:用?代替参数
  • 步骤
    1. 导入jar包:mysql-connector-java-版本号-bin.jar
    2. 注册驱动
    3. 获取连接对象Connection
    4. sql语句
      • 注意:sql语句的参数使用?作为占位符,如select * from login where username = ? and password = ?
    5. 获取执行sql语句的对象PreparedStatement
    6. 给?赋值
      • 方法:setXXX(参数1, 参数2)
        • 参数1:?的位置编号,从1开始
        • 参数2:?的值
    7. 执行sql操作
    8. 得到结果
    9. 解析结果
    10. 释放资源

  那么我们现在使用PreparedStament类对象防止上面的SQL注入

  • 实现代码3-1:

      package cn.gaogzhen.jdbc;
    
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.util.Scanner;
    
      import cn.gaogzhen.util.JDBCUtils;
    
      public class JDBCDemo8 {
      	public static void main(String[] args) throws SQLException {
      		Scanner sc = new Scanner(System.in);
      		System.out.println("请输入用户名:");
      		String username = sc.nextLine().trim();
      		System.out.println("请输入密码:");
      		String password = sc.nextLine().trim();
      		sc.close();
      		String res = login(username, password)? "登录成功": "登录失败";
      		System.out.println(res);
       }
    
      	public static boolean login(String username, String password) throws SQLException {
      		if(username == null || password == null) return false;
      		Connection conn = JDBCUtils.getConnection();
      		String sql = "select * from login where username = ? and password = ?";
      		PreparedStatement pstm = conn.prepareStatement(sql);
      		pstm.setString(1, username);
      		pstm.setString(2, password);
      		ResultSet rs = pstm.executeQuery();
      		boolean flag = rs.next();
      		JDBCUtils.close(rs, pstm, conn);
      		return flag;
      	}
      }
    

测试结果:

请输入用户名:
sdfasf
请输入密码:
sdfas' or '1'='1#
登录失败

后记

本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785

前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章