JDBC解决sql注入问题

JDBC解决sql注入问题,第1张

JDBC解决sql注入问题
本程序是模拟用户登录
并且解决SQL注入问题
sql注入的根本原因是:先进行字符串的拼接,再进行编译
程序说明:本程序的输入采取了scanner.nextline()方法 即意味着可以接收一行的密码
而密码是sql语言的一部分,因此可以创建 or 关键字破坏sql的where条件
例如:

 

此时人为地破坏了sql正常的语句

原本的代码:

            //3.获取数据库 *** 作对象
            stmt = conn.createStatement();
            //4.执行sql语句

//            mysql语句有单引号如何写入String
//            1.首先按照sql语句写下你要查询的语句,变量的地方先空着
//            2.然后在单引号里加双引号和两个加号   如  '"++"'      此时再向两个加号之间加上变量。
//            String sql = "select * from t_user where login_name ='' and login_pwd=''";
            String sql = "select * from t_user where login_name ='"+loginname+"' and login_pwd='"+loginpwd+"'";
//            3.但是这种情况会出现sql的注入问题(即输入的密码为   123 or '1'= 1 )
            rs = stmt.executeQuery(sql);//rs返回的是光标

解决方法为:改变原本的Statement *** 作对象,使用预编译的 *** 作对象PreparedStatement

package JDBC;

import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Scanner;



public class JDBClogin_user {
    public static void main(String[] args) {
//        自动创建函数:只需要在未创建的函数名处使用alt+enter 即可为其创建函数
        //初始化界面
        Map userlogin_info = initUI();
        //链接数据库,验证用户名和密码是否正确
        boolean ok = check_nameandpwd(userlogin_info.get("loginname"),userlogin_info.get("loginpwd"));

        System.out.println(ok ? "登录成功" : "登录失败");//   ?为正,登录成功,否则登录失败
    }

    private static boolean check_nameandpwd(String loginname, String loginpwd) {

        //数据库的六部    哐哐哐打出来或者找之前写好的模板直接复制   这里采取第二种注册驱动的方法
        Connection conn = null;
//        Statement stmt = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        //资源绑定器
        ResourceBundle bundle = ResourceBundle.getBundle("resourses/db");
        String driver= bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password = bundle.getString("password");
        //下面的模板就是 try{...}catch{...}finally{...}
        try{
            //1.注册驱动的第二种方式:类加载注册
//            Class.forName("com.mysql.jdbc.Driver");//可以写到配置文件当中
            Class.forName(driver);
            //2.获取连接
//            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/trade_for_book","root","002415");
            conn = DriverManager.getConnection(url,user,password);
            //3.获取数据库 *** 作对象
//            stmt = conn.createStatement();
            String sql = "select * from t_user where login_name = ? and login_pwd= ?";//一个问号是一个占位符,只能接受一个值
            stmt = conn.prepareStatement(sql);
            //给问号传值   那么无论你输入的有什么关键字,最终只是一个值,不会改变sql语句的条件
            stmt.setString(1,loginname);
            stmt.setString(2,loginpwd);
            //4.执行sql语句

//            mysql语句有单引号如何写入String
//            1.首先按照sql语句写下你要查询的语句,变量的地方先空着
//            2.然后在单引号里加双引号和两个加号   如  '"++"'      此时再向两个加号之间加上变量。
//            String sql = "select * from t_user where login_name ='' and login_pwd=''";
//            String sql = "select * from t_user where login_name ='"+loginname+"' and login_pwd='"+loginpwd+"'";
//            3.但是这种情况会出现sql的注入问题(即输入的密码为   123 or '1'= 1 )
//            rs = stmt.executeQuery(sql);//rs返回的是光标
            rs = stmt.executeQuery();//预编译就不需要传sql语句了
//            System.out.println(sql);
            if (rs.next()){
                return true;
            }else {
                return false;
            }
        }catch(Exception e){
            e.printStackTrace();

        }finally {
            if (rs != null){
                try{
                    rs.close();
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }

            if (stmt != null){
                try{
                    stmt.close();
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }

            if (conn != null){
                try{
                    conn.close();
                }catch(SQLException e){
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    private static Map initUI(){
        System.out.println("欢迎使用该系统,请输入你的用户名和密码");
        //读取String用next(),以空格划分
        Scanner s = new Scanner(System.in);
        System.out.print("用户名:");
//        String loginname = s.next();
        String loginname = s.nextLine();
        System.out.print("密码:");
//        String loginpwd = s.next();
        String loginpwd = s.nextLine();

        //将用户名和密码放到Map集合中
        Map userlogin__info = new HashMap<>();
        userlogin__info.put("loginname",loginname);
        userlogin__info.put("loginpwd",loginpwd);

        //返回Map
        return userlogin__info;
    }
}
//    数据库内容
//    drop table if exists t_user;
//        create table t_user(
//        id int primary key auto_increment,    auto_increment表示自增
//        login_name varchar(255) unique ,
//        login_pwd varchar(255),
//        real_name varchar(255)
//        );
//        insert into t_user(login_name,login_pwd,real_name) values('admin','123','孙子昂');
//        insert into t_user(login_name,login_pwd,real_name) values('admin01','123','xx02');
//
//        select *form t_user;

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5717946.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存