一.實作功能:
1、需求:
模擬用戶登錄功能的實作
2、業務描述:
程式運行的時候,提供輸入的入口,可以讓用戶輸入用戶名和密碼
用戶輸入用戶名和密碼后,提交資訊,java程式收集到用戶資訊
java程式連接資料庫驗證用戶名和密碼是否合法,并顯示結果(登錄成功/登錄失敗)
3、用戶資訊表
+----+-----------+----------+----------+
| id | loginName | loginPwd | realName |
+----+-----------+----------+----------+
| 1 | abc | 123 | 張三 |
| 2 | wwe | 456 | 李四 |
+----+-----------+----------+----------+
二.代碼實作:
import java.sql.*;
import java.util.*;
/*
實作功能:
1、需求:
模擬用戶登錄功能的實作
2、業務描述:
程式運行的時候,提供輸入的入口,可以讓用戶輸入用戶名和密碼
用戶輸入用戶名和密碼后,提交資訊,java程式收集到用戶資訊
java程式連接資料庫驗證用戶名和密碼是否合法,并顯示.結果(登錄成功/登錄失敗)
3、用戶資訊表
+----+-----------+----------+----------+
| id | loginName | loginPwd | realName |
+----+-----------+----------+----------+
| 1 | abc | 123 | 張三 |
| 2 | wwe | 456 | 李四 |
+----+-----------+----------+----------+
*/
public class JDBCTest01 {
public static void main(String[] args) {
//初始化界面(用戶輸入賬號和密碼)
Map<String,String> userLoginInfo = initUI();
//驗證用戶名和密碼(JDBC)
boolean loginSuccess = login(userLoginInfo);
//顯示結果:
System.out.println(loginSuccess==true?"登錄成功":"登錄失敗");
}
/**
* 驗證用戶登錄資訊是否正確
* @param userLoginInfo 用戶登錄資訊
* @return false 表示登錄失敗,true 表示登錄成功
*/
private static boolean login(Map<String, String> userLoginInfo) {
//打標記(登錄結果)
boolean loginSuccess = false;
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1、注冊驅動
Class.forName("com.mysql.cj.jdbc.Driver");
//2、獲取連接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode",
"root","888");
//3、獲取資料庫操作物件
statement = connection.createStatement();
//4、執行sql
String sql = "select * from t_user where loginName = '"+userLoginInfo.get("loginName")+"'" +
" and loginPwd = '"+userLoginInfo.get("loginPwd")+"' ";
resultSet = statement.executeQuery(sql);
//5、處理結果集
//不需要while結果集,因為查詢結果不是 無 就是 1條記錄
if (resultSet.next()){
loginSuccess = true;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//從小到大分別關閉三個資源
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//最后回傳 登錄結果(boolean)
return loginSuccess;
}
/**
* 初始化用戶界面
* @return 用戶的用戶名和密碼(Map)
*/
private static Map<String, String> initUI() {
Scanner s=new Scanner(System.in);
System.out.println("用戶名:");
String loginName = s.nextLine();
System.out.println("密碼:");
String loginPwd = s.nextLine();
//用 HashMap(鍵值對的方式)存盤用戶輸入的 賬號和密碼
Map<String,String> userLoginInfo = new HashMap<>();
userLoginInfo.put("loginName",loginName);
userLoginInfo.put("loginPwd",loginPwd);
return userLoginInfo;
}
}
三.效果展示:
1.輸入合法的用戶名和密碼:
點擊查看
用戶名:
abc
密碼:
123
登錄成功
Process finished with exit code 0
點擊查看
用戶名:
wwe
密碼:
456
登錄成功
Process finished with exit code 0
2.輸入不合法的用戶名和密碼:
點擊查看
用戶名:
hahaha
密碼:
123
登錄失敗
Process finished with exit code 0
四.SQL注入現象:
1.用戶為:任意字符
密碼為:任意字符' or '1'='1
用戶名:
yyds
密碼:
yyds' or '1'='1
登錄成功
Process finished with exit code 0
當用戶輸入資訊為這種情況時,也能登錄成功,這種現象叫做 SQL注入現象;因為以上字符正好完成了sql陳述句的拼接,然后此(本不應該被編譯的)sql陳述句被發送給DBMS,DBMS進行編譯,這樣正好把用戶提供的"非法資訊"編譯進去,導致原sql陳述句的含義被扭曲了;
2.總結SQL注入的根本原因是:
用戶輸入的資訊中含有sql陳述句的關鍵字,并且這些關鍵字參與sql陳述句的編譯程序,導致sql陳述句的原意被扭曲,進而達到sql注入;
3.如何解決SQL注入問題?
SQL注入問題根本在于"輸入的非法資訊"不應該被編譯,所以只要讓用戶提供的資訊不參與SQL陳述句的編譯,就解決了問題,那么就必須使用 --- java.sql.PreparedStatement;
4.java.sql.PreparedStatement:
PreparedStatement 介面繼承了 java.sql.PreparedStatement;
PreparedStatement 屬于預編譯的資料庫物件;
PreparedStatement 的原理是:預先對SQL陳述句的框架進行編譯,然后再給SQL陳述句傳值;
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/399542.html
標籤:其他
