【问题标题】:Accessing user database from multiple classes从多个类访问用户数据库
【发布时间】:2016-01-09 02:41:07
【问题描述】:

我正在创建一个基本的注册/登录用户名/密码数据库,我想知道我的方法是否正确。我对代码只是工作不满意,我希望它也干净高效。

用户可以访问互联网登录页面,输入凭据,然后基本登录。我有一个数据库类,它创建帐户并检查输入的凭据是否正确。

所以,数据库类:

public class Database {

    private Connection          connection          = null;
    private PreparedStatement   preparedStatement   = null;
    private ResultSet           resultSet           = null;

    // Method for registering a new account. Credentials are added into the database.
    public void registerAccount(String username, String password, String ipAddress) {

        try {

            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
            connection = DriverManager
            .getConnection("jdbc:derby:C:\\DB;create=true;upgrade=true");
            String query = "INSERT INTO Users (username, password, ip_address) VALUES" + "(?,?,?)";
            preparedStatement = connection.prepareStatement(query);
            preparedStatement.setString(1, username);
            preparedStatement.setString(2, password);
            preparedStatement.setString(3, ipAddress);
            preparedStatement.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            close();
        }

    }

    private void close() {

        try {

            if (resultSet != null) {
                resultSet.close();
            }
            if (preparedStatement != null) {
                preparedStatement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

例如:当用户点击提交登录时,Database类内部的一个方法被调用:

// Checks if credetials are correct.
public boolean checkLogin(String username, String password) {

    try {

        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        connection = DriverManager
                .getConnection("jdbc:derby:C:\\DB;create=true;upgrade=true");
        String query = "SELECT username, password from Users WHERE username = ? AND password = ?";
        preparedStatement = connection.prepareStatement(query);
        preparedStatement.setString(1, username);
        preparedStatement.setString(2, password);
        resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            String user = resultSet.getString("username");
            String pass = resultSet.getString("password");
            if (username.equalsIgnoreCase(user)) {
                if (password.equals(pass)) {
                    return true;
                }
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        close();
    }
    return false;
}

我在 Database 类中还有一些其他方法可以检查注册时是否没有使用用户名,或者帐户是否已经在特定 IP 上注册等。这是一种好的做法还是有更好、更有效的方法实现这一目标? 谢谢!

【问题讨论】:

  • 对我来说很好。不过,由于这是一个 Web 系统,我建议您查看像 Spring Security 这样的安全框架,并将这种责任委托给一个已经有据可查的框架。在您的代码中,我建议只使用一些哈希技术,以便您对用户密码进行哈希处理并插入它,当您检查您对用户发送的字符串进行哈希处理并进行比较时。这样即使您看不到用户密码。

标签: java database jdbc


【解决方案1】:

通过用户名查询记录得到加密后的密码,并与用户输入的加密后的密码进行比较。

这是一个参考How can I hash a password in Java?。 PBKDF2 是一个很好的密码哈希算法。

byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 128);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
System.out.printf("salt: %s%n", enc.encodeToString(salt));
System.out.printf("hash: %s%n", enc.encodeToString(hash));

Here is the PBKDF2 one in python。你很容易理解。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-07
相关资源
最近更新 更多