JDBC实现简单登录功能


首先我们模拟下简单的登录功能:

简单需求:

  模拟用户登录的简单实现

业务描述:

  程序运行 的时候,提供一个输入的人口,可以使用输入用户名个密码,校验用户名和密码是否合法,数据库中是否存在用户

  合法登录成功,否则注册登录

数据准备:

  设计数据库表,通常我们使用建模工具:PowerDesigner

 

接下来上代码:

 db.properties配置文件如下:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user
user=root
password=guisha

实现如下:

package com.guisha.JDBC.Logn;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;

public class JDBCTest {
    public static void main(String[] agre) {
        //获取登录时的用户和密码
        Map<String, String> loginInfo = loginInfo();
        //获取用户名登录验证
        boolean loginSuccess = login(loginInfo);
        //输出结果验证
        System.out.println(loginSuccess ? "登录成功!" : "请注册登录!");
    }

    private static boolean login(Map<String, String> loginInfo) {
        //登录标记
        boolean flag = false;
        //定义用户名和登录密码
        String loginName = loginInfo.get("loginName");
        String loginPwa = loginInfo.get("loginPwa");
        //使用的接口
        Connection conn = null;
        Statement stan = null;
        ResultSet result = null;

        try {
            InputStream input = JDBCTest.class.getClassLoader().getResourceAsStream("db.properties");
            Properties property = new Properties();
            try {
                //装载配置文件
                property.load(input);
                String driver = property.getProperty("driver");
                String url = property.getProperty("url");
                String user = property.getProperty("user");
                String password = property.getProperty("password");
                //注册驱动
                Class.forName(driver);
                //从输入字节流中读取属性列表(键和元素对)。输入流采用load(Reader)中指定的简单的面向行的格式,并假定使用ISO 8859-1字符编码。
                try {
                    //创建链接
                    conn = DriverManager.getConnection(url, user, password);
                    //获取数据库操作对象
                    stan = conn.createStatement();
                    //执行Sql,获取数据
                    String sql = "select * from loginname where NAME='" + loginName + "' and NAMEPASS= '" + loginPwa + "' ";
                    // 查询结果集
                    result = stan.executeQuery(sql);
                    //判断
                    if (result.next()){
                        flag = true;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }finally {
            //释放资源
            if (result != null){
                try {
                    result.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            //释放资源
            if (stan != null){
                try {
                    stan.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            //释放资源
            if (conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //返回标识
        return flag;
    }

    public static Map<String, String> loginInfo() {
        //接受键盘输入
        Scanner scanner = new Scanner(System.in);
        //输入用户名
        System.out.println("请输入用户名:");
        String loginName = scanner.nextLine();
        //输入密码
        System.out.println("请输入密码:");
        String loginPwa = scanner.nextLine();
        //创建键值对集合
        Map<String, String> map = new HashMap<String, String>();
        //将数据添加到map集合对象中
        map.put("loginName", loginName);
        map.put("loginPwa", loginPwa);
        //返回集合对象
        return map;
    }
}

  

我们需要了解SQL注入

 

 

   以上代码中执行执行SQL部分,这里完成了SQL语句的拼接,而executeQuery这里是将sql语句发送给DBMS进行代码编译

  正好将用户提供的"非法信息"编译进去,导致原SQL语句的含义被扭曲,会导不正常的操作变的正常、

导致SQL注入的根本原因是什么?

  用户输入的信息中包含SQL语句的关键字,并且这些关键字参与sql语句的编译过程,导致SQL语句原意改变,进而达到SQL注入的效果(不能小视,可能会造成数据库崩溃或者被改变)

 

 

解决SQL注入问题?

  首先我们知道出现SQL注入的原因是用户在提供的信息包含SQL语句的关键字,并且在传给DBMS预编译时传入了非法的SQL信息,那么,只要用户提供的信息不参与SQL语句的编译过程,就可以解决问题(即使信息中包含SQL语句的关键字,但是不参与预编译,不起作用)。

  想要用户信息不参与SQL预编译,就需要使用java.sql.PreparedStatement接口,此接口继承了java.sql.Statement。

  PreparedStatement是属于预编译的数据库操作对象,原理是:预先对SQL语句的框架进行预编译,然后再给SQL语句传值

我们对代码进行修改:

package com.guisha.JDBC.Logn;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;

public class JDBCTest {
    public static void main(String[] agre) {
        //获取登录时的用户和密码
        Map<String, String> loginInfo = loginInfo();
        //获取用户名登录验证
        boolean loginSuccess = login(loginInfo);
        //输出结果验证
        System.out.println(loginSuccess ? "登录成功!" : "请注册登录!");
    }

    private static boolean login(Map<String, String> loginInfo) {
        //登录标记
        boolean flag = false;
        //定义用户名和登录密码
        String loginName = loginInfo.get("loginName");
        String loginPwa = loginInfo.get("loginPwa");
        //使用的接口
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet result = null;

        try {
            InputStream input = JDBCTest.class.getClassLoader().getResourceAsStream("db.properties");
            Properties property = new Properties();
            try {
                //装载配置文件
                property.load(input);
                String driver = property.getProperty("driver");
                String url = property.getProperty("url");
                String user = property.getProperty("user");
                String password = property.getProperty("password");
                //注册驱动
                Class.forName(driver);
                //从输入字节流中读取属性列表(键和元素对)。输入流采用load(Reader)中指定的简单的面向行的格式,并假定使用ISO 8859-1字符编码。
                try {
                    //创建链接
                    conn = DriverManager.getConnection(url, user, password);
                    //获取数据库操作对象
                    //SQL语句,其中一个 ? ,表示一个占位符,一个?将来接受一个“值”,注意:占位符不能使用 ' ' 括起来
                    String sql = "select * from loginname where NAME= ? and NAMEPASS = ? ";
                    ps= conn.prepareStatement(sql);
                    //给占位符串 “值” (第一个? 下标为1,第二个为2,切记 JDBC中所有的下标从1开始)
                    ps.setString(1,loginName);
                    ps.setString(2,loginPwa);
                    //执行Sql,获取数据对语句进行预编译
                    // 获取结果集
                    result = ps.executeQuery();
                    //判断
                    if (result.next()){
                        flag = true;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }finally {
            //释放资源
            if (result != null){
                try {
                    result.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            //释放资源
            if (ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            //释放资源
            if (conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //返回标识
        return flag;
    }

    public static Map<String, String> loginInfo() {
        //接受键盘输入
        Scanner scanner = new Scanner(System.in);
        //输入用户名
        System.out.println("请输入用户名:");
        String loginName = scanner.nextLine();
        //输入密码
        System.out.println("请输入密码:");
        String loginPwa = scanner.nextLine();
        //创建键值对集合
        Map<String, String> map = new HashMap<String, String>();
        //将数据添加到map集合对象中
        map.put("loginName", loginName);
        map.put("loginPwa", loginPwa);
        //返回集合对象
        return map;
    }
}

 

上一篇:Java中使用JDBC连接数据库                                        

下一篇:Statement和PreparedSatement的对比


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM