JDBC实现用户登录:
public class jdbcTest06{
public satic void main(String[] args){
Map<String,String> userLoginInfo initUI();
boolean loginSuccess = login(userLoginInfo);
System.out.println(loginSuccess ? "登录成功" : "登录失败");
}
private static boolean login(Map<String,String> userLoginInfo){
boolean loginSuccessornot = false;
String loginName = userLoginInfo.get("loginName");
String loginPwd = userLoginInfo.get("loginPwd");
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","333");
stmt = conn.creatStatement();
String sql = "select * from t_user where loginName '"+loginName+"' and '"+loginPwd+"'";
rs = stmt.executeQuery(sql);
if(rs.next()){
loginSuccessornot = true;
}else{
loginSuccessornot = false;
}
}catch(SQLException 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 loginSuccessornot;
}
private static Map<String,String> iniUT(){
Scanner s = new Scanner(System.in);
System.out.println("用户名:");
String loginName = s.nextLine();
System.out.println("密码:");
String loginPwd = s.nextLine();
Map<String,String> userLoginInfo = new HaspMap<>();
userLoginInfo.put("loginName","loginName");
userLoginInfo.put("loginPwd","loginPwd");
return userLoginInfo;
}
}
??
SQL注入
当前程序存在问题:
??输入: ????用户名:fdsa ????密码:fdsa’ or ‘1’ = ‘1 ??输入: ????登录成功 ( 数据库中不存在这条数据 )
这种现象被成为SQL注入
问题代码块:
jade,mysql
Statement stmt = null;
stmt = conn.creatStatement();
String sql = "select * from t_user where
'"+loginName+"' and '"+loginPwd+"'";
rs = stmt.executeQuery(sql);
以上代码块解析:
??获取数据库操作对象 stmt 后执行SQL语句将传了loginName 和 loginPwd 两个参数的SQL语句作为参数传给了 executeQuery() 方法 ??然后 executeQuery() 方法进行编译,就会把 fdsa’ or ‘1’ = ‘1 作为sql语句一起编译了,
看看编译后的sql语句:
sql: "select * from t_user where
loginName = 'fdsa' and loginPwd = 'fdsa' or '1' = '1'"
??可以看到查询语句的where条件变成了 ???? loginName = 'fdsa' and loginPwd = 'fdsa' or '1' = '1'"
??意思就是 where(loginName = 'fdsa' and loginPwd = 'fdsa') 或者 ('1' = '1')
??而'1' = '1' 恒成立,所以无论怎么查询都能查到结果,甚至是将所有的用户账号密码都查了出来,最后完成登录
所以出现SQL注入的关键是: ??用户输入的非法信息被数据库操作系统编译了,例如用户输入了含有SQL语句的关键字,并且这些关键字参与了SQL语句的编译过程 ??
解决SQL注入
??只要用户提供的信息不参与SQL编译过程,即使提供的信息含有关键字等非法信息,但是只要不参加数据库操作系统的编译九不会形成注入
??要想用户信息不参与SQL语句的编译,那必须适合用java.sql.PreparedStatement
??PreparedStatement 接口集成了java.sql.Statement,PreparedStatement 是属于预编译的数据库操作对象
??PreparedStatement 的原理是预先对SQL语句的框架进行编译,然后再给SQL语句传值
解决SQL注入的关键是: ??用户提供的信息中即使含有sql语句的关键字,但是这些关键字并没有参与编译,不起作用
解决注入代码:
package com.hyqwsq.jdbc;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class jdbcTest06 {
public static void main(String[] args) {
Map<String,String> userLoginInfo = initUI();
boolean loginSuccess = login(userLoginInfo);
System.out.println(loginSuccess ? "登录成功" : "登录失败");
}
private static boolean login(Map<String, String> userLoginInfo) {
boolean loginSuccessornot = false;
String loginName = userLoginInfo.get("loginName");
String loginPwd = userLoginInfo.get("loginPwd");
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/hyqwsq","root","13903014064");
String sql = "select * from t_user where loginName = ? and ?";
ps = conn.prepareStatement(sql);
ps.setString(1,loginName);
ps.setString(2,loginPwd);
rs = ps.executeQuery(sql);
if(rs.next()){
loginSuccessornot = true;
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally {
if(rs != null){
try {rs.close();} catch (SQLException throwables) {throwables.printStackTrace();}}
if(ps != null){
try {ps.close();} catch (SQLException throwables) {throwables.printStackTrace();}}
if(conn != null){
try {conn.close();} catch (SQLException throwables) {throwables.printStackTrace();}}
}
return loginSuccessornot;
}
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();
Map<String,String> userLoginInfo = new HashMap<>();
userLoginInfo.put("loginName","loginName");
userLoginInfo.put("loginPwd","loginPwd");
return userLoginInfo;
}
}
|