所以我正在java web app上构建一个注册/登录表单,我想让它近乎完美。我的意思是安全,快速,干净的代码。
所以现在我的代码就是这样。我有一个User的私有结构,有setter和getter以及注册方法:
db dbconn = new db();
Connection myconnection = dbconn.Connection();
String sqlString = "INSERT INTO users (name, password) VALUES ('"+Name+"','"+Password+"')";
try {
Statement myStatement = null;
myStatement.executeUpdate(sqlString);
myStatement.close();
myconnection.close();
}
catch (SQLException e) {
System.err.println(e);
}
但事情是我听到(不确定)只是运行这样的SQL查询是不好的例子,我不应该这样做?所以我只是想知道,将用户注册到MySQL数据库的最佳方法是什么?使用程序?或者使用类似的语句也是有效的?
答案 0 :(得分:4)
如果您只使用JDBC(而不是OR映射器),则应出于安全原因使用预准备语句。你这样做的方式允许SQL注入。
问题:如果像你一样连接参数值,可能会改变查询。
示例:如果Name
的值为x','y');DELETE FROM users;SELECT * FROM users WHERE name in ('whatever
查询将变为:
INSERT INTO users (name, password) VALUES ('x','y');DELETE FROM users;SELECT * FROM users WHERE name in ('whatever', 'password')
现在执行该查询,您可能想知道所有用户都去了哪里。
使用PreparedStatement
语句如下所示:
PreparedStatement pst = myconnection.prepareStatement("INSERT INTO users (name, password) VALUES (?,?)");
pst.setString(1, Name); //btw, Java coding conventions state it should be "name" instead of "Name"
pst.setString(2, Password); //your password should be hashed and salted btw!
pst.executeUpdate();
注意如何在语句中使用单引号。 PreparedStatement
将为您处理,并且还会转义值以防止注入。
第二个想法(从设计的角度来看):您可能会考虑将用户注册等与保存数据的用户对象分开(请参阅单一责任原则)。这只是一个建议,肯定有其他人不同意(有效的论据,通常取决于情况)。
答案 1 :(得分:0)
db dbconn = new db();连接myconnection = dbconn.Connection();
到实用程序类。
查看一些关于如何操作的真实示例,例如使用finally块来关闭语句和连接(在finally块中也会看到try / catch看起来很难看)
这里有一个link到JDBC最佳实践凭证(虽然有点高级)
一对参考小教程: