我有一个DBHandler java类,它包含多个方法,这是其中之一:
public Boolean authenticate(User u) throws SQLException
{
Boolean f=false;
// connect to data base
try {
connectToDB();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
// retrieve users based on the last name
Statement s = null;
try {
String query = "select * from user where email='"+u.getEmail()+"' and password='"+u.getPassword()+"'";
s = conn.createStatement();
ResultSet rs= s.executeQuery(query);
if (rs.next()){//also rs.first() didnt work
f= true;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
// close both the SQL statement and the DB connection
if (s != null) {s.close();}
if (conn != null){conn.close();}
}
return f;
}
此方法检查用户是否存在于数据库中并返回布尔值。
我在servlet中调用此方法并打印返回的值,如下所示:
User users= new User();
users.name="lamatat";
users.email="lamatata@hotmail.com";
users.password="1234567890";
users.id=3;
DBHandler db= new DBHandler();
Boolean b=db.authenticate(users);
out.println("<h1>Servlet Login at " + b + "</h1>");
但即使是虚假的......这总是会回归......
我不知道错误是什么或在哪里?
任何帮助表示赞赏!
答案 0 :(得分:0)
rs.equals("")
- ResultSet
很可能永远等于String
,因此f = false
将不会在此处调用。正如其他人已经说过的那样,使用f = rs.next()
。
基本上你做的是:
ResultSet rs= s.executeQuery(query);
boolean f = rs.next(); //if true, the query found a matching user
除此之外,您不应该假设用户在开始时已经过身份验证(Boolean f=true;
),但假设他未经过身份验证,只有在身份验证成功的情况下才更改标志。这样,当您遇到错误时,您将无法获得经过身份验证的用户。在大多数情况下,最好在发生错误时拒绝授予访问权限而不是授予权限。
关于安全性的另一个提示:您应该在数据库中存储散列密码(最好也加密),并为用户输入的普通密码创建一个散列,并在查询中使用此散列。
更新:重新查询您的查询还有另一个潜在的安全问题。如果将查询参数添加到"... where email='"+u.getEmail()+"' ..."
中的查询字符串中,则您很容易受到SQL注入攻击,即攻击者可以使用“email”crap' or true; --
,这将导致此查询字符串:
select * from user where email='crap' or true;-- and password='whatever'
攻击者因此可以破解他进入系统的方式,因为查询总会返回一些东西。 密码也是如此,至少除非经过哈希处理。
因此,您最好在这里使用PreparedStatement
。
答案 1 :(得分:0)
您没有查看实际记录,请尝试以下操作:
ResultSet rs= s.executeQuery(query);
f = rs.next();// true, if record exist else false
在您的情况下,您验证rs
对象是否等于""
空白字符串,并且您想要验证数据是错误的。
修改强>
以上更改适用于authenticate()
,请使用上述代码替换以下代码
ResultSet rs= s.executeQuery(query);
if (rs.first()){
f= true;
}
P.S。在运行参数的情况下使用PreparedStatement
来进行SQL查询。
答案 2 :(得分:0)
根据您在数据库上执行的代码和命令,如果您检查rs.next();
,您可以获得是否有像您这样的用户正在通过。像这样:
if (rs.next()){
f= true;
}