PreparedStatement,注册攻击,模拟用户登录

JDBC-模拟用户登录

案例需求:
  模拟用户登录,Statement对象完成
开发步骤:
  1.准备环境,导入JDBCUtils工具类,mysql-connector-java-5.1.10-bin.jar包,JUnit 4 jar包 
  2.创建main方法,提示用户登录
  3.创建login方法,用来验证用户是否存在,去查询user表,根据用户名和密码,利用jdbc完成,JDBCUtils工具类
  
方式一:当我们的用户名输入的值为jack’# /jack’ or’1=1’时会产生一新现象:只输入用户名不输入密码可以登录成功。
本质上是因为SQL中出现了SQL关键字(# / or),使得SQL语义发生了变化。出现SQL注入攻击问题, 
 
方式二:给出了解决方案,利用PreparedeStatement对象开发,可以成功的避免攻击问题

总结:1.防止 SQL注入攻击问题,本质上是将SQL的关键字当做一个普通的字符串来处理的。
2.省去了参数拼接的麻烦,利用?来作为占位符,将SQL的参数和SQL的骨架分隔开。?的值通过ps.setString(index,username)
3.提高程序的效率,执行sql的时候,先将SQL骨架缓存,减少了数据库的交互提高程序访问效率
用户表:
PreparedStatement,注册攻击,模拟用户登录_第1张图片

代码实现如下

package on.login_用户登录;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

import on.tedu.Util_工具类.JDBCUtils;

/**
 * 这个类用来模拟用户登录
 * 开发步骤:
 * 1.创建main方法,提示用户登录
 * 2.创建login方法,用来验证用户是否存在
 * 
 * @date 2018年3月26日
 *
 */
public class LoginUser {

    //1.创建main方法,提示用户登录
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);    
        System.out.println("请您输入用户名:");
        String username = sc.nextLine();
        System.out.println("请您输入密码:");
        String password =sc.nextLine();
        //2.创建login方法,用来验证用户是否存在
        login(username,password);

    }

    //用来验证用户是否存在
    //去查询user表,根据用户名和密码
    private static void login(String username, String password) {
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        //利用可以防止SQL注入攻击的对象
        PreparedStatement ps =null;
        try {
            //利用jdbc完成,JDBCUtils工具类完成
            //1.获取数据库连接
            conn= JDBCUtils.getConnection();
            //2.获取传输器
            //st=conn.createStatement();

            /**
             * 方式一产生了注入攻击问题 jack'# 和 jack' or '1=1
             */
            //3.执行SQL
            /*  String sql="select * from user where username='"+username+"' and password='"+password+"'";
                rs=st.executeQuery(sql);*/

            //自己的思路
            /*          String name=null;
            String pass=null;
            while(rs.next()){
                 name=rs.getString(2);
                 pass=rs.getString(3);
            }*/

            /**
             * 方式二:PerparedStatement对象
             * 执行SQL
             */
            //利用connection对象产生PerparedStatement预编译传输器对象
            //? 叫做占位符 ,SQL的名字叫做骨架
            String sql ="select * from user where username=? and password=?";
            ps=conn.prepareStatement(sql);
            //设置参数值,数字的顺序和 ? 的顺序一致
            ps.setString(1, username);//匹配第一个?要输入的值
            ps.setString(2, password);
            rs= ps.executeQuery();

            //4.解析结果集
            if(rs.next()){
                System.out.println("恭喜您,登录成功!");
            }else{
                System.out.println("用户名和密码输入错误!请重新输入");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //5.关闭资源
            JDBCUtils.close(conn, st, rs);
        }
    }
}

运行结果:
PreparedStatement,注册攻击,模拟用户登录_第2张图片

你可能感兴趣的:(注册攻击)