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