0

我正在使用 JDBC 检查数据库中的用户名和密码以授予对我的 gui 的登录访问权限,但是当我尝试测试 JDBC 是否正常工作时,当输入错误的用户名和密码时,它不会阻止访问..

下面是我的代码,我相信它正确连接了数据库,因为当我按下登录按钮时,它会输出运行检查登录和用户已验证。

class usernamecheck {

    static final String DATABASE_URL = "jdbc:mysql://localhost:3306/mysql";
    static final String USERNAME = "root";
    static final String PASSWORD = "root";

   // launch the application
    public static boolean checkLogin(String username, String password)
            throws SQLException {
        System.out.print("Running Check Login \n");

        Connection connection = null; // manages connection
        PreparedStatement pt = null; // manages prepared statement

        // connect to database usernames and query database
        try {

            // establish connection to database
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection con = DriverManager.getConnection(DATABASE_URL, "root", "root");

            // query database
            pt = con.prepareStatement("select userName,password from mysql.person where userName=?");

            // process query results
            pt.setString(1, username);
            ResultSet rs = pt.executeQuery();
            String orgUname = "", orPass = "";
            while (rs.next()) {
                orgUname = rs.getString("userName");
                orPass = rs.getString("password");
            } //end while
            if (orPass.equals(password)) {
                //do something
                return true;
            } else {
                //do something
            }
        }//end try
        catch (Exception e) {
        } //end catch  
        return false;
    } //end main
}

带有 GUI 的代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.sql.*;


public class Login extends JFrame {

    private JTextField jtfUsername, jtfPassword;
    private JButton backButton, loginButton;
    private JMenuItem jmiLogin, jmiBack, jmiHelp, jmiAbout;

    Login() {
        //create menu bar
        JMenuBar jmb = new JMenuBar();

        //set menu bar to the applet
        setJMenuBar(jmb);

        //add menu "operation" to menu bar
        JMenu optionsMenu = new JMenu("Options");
        optionsMenu.setMnemonic('O');
        jmb.add(optionsMenu);

        //add menu "help"
        JMenu helpMenu = new JMenu("Help");
        helpMenu.setMnemonic('H');
        helpMenu.add(jmiAbout = new JMenuItem("About", 'A'));
        jmb.add(helpMenu);

        //add menu items with mnemonics to menu "options"
        optionsMenu.add(jmiLogin = new JMenuItem("Login", 'L'));
        optionsMenu.addSeparator();
        optionsMenu.add(jmiBack = new JMenuItem("Back", 'B'));

        //panel p1 to holds text fields
        JPanel p1 = new JPanel(new GridLayout(2, 2));
        p1.add(new JLabel("Username"));
        p1.add(jtfUsername = new JTextField(15));
        p1.add(new JLabel("Password"));
        p1.add(jtfPassword = new JPasswordField(15));

        //panel p2 to holds buttons
        JPanel p2 = new JPanel(new FlowLayout());
        p2.add(backButton = new JButton("Back"));
        p2.add(loginButton = new JButton("Login"));

        //Panel with image??????

        //add panels to frame
        JPanel panel = new JPanel(new GridLayout(2, 1));
        panel.add(p1, BorderLayout.CENTER);
        panel.add(p2, BorderLayout.SOUTH);
        add(panel, BorderLayout.CENTER);
        setTitle("Main Page");


        //listners for exit menuitem and button
        jmiBack.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Welcome welcome = new Welcome();
                welcome.setVisible(true);
                welcome.setSize(500, 500);
                welcome.setLocationRelativeTo(null);
                registerInterface regFace = new registerInterface();
                regFace.setVisible(false);
                Login.this.dispose();
                Login.this.setVisible(false);
            }
        });

        backButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Welcome welcome = new Welcome();
                welcome.setVisible(true);
                welcome.setSize(500, 500);
                welcome.setLocationRelativeTo(null);
                registerInterface regFace = new registerInterface();
                regFace.setVisible(false);
                Login.this.dispose();
                Login.this.setVisible(false);
            }
        });

        //listner for about menuitem
        jmiAbout.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null,
                        "This is the login panel"
                        + "\n Assignment for University",
                        "About", JOptionPane.INFORMATION_MESSAGE);
            }
        });

        //action listeners for Login in button and menu item
        loginButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    usernamecheck.checkLogin(jtfUsername.getText(), jtfPassword.getText()); {
                    System.out.println("User is validated");
               }
                } catch (SQLException se) {
                }
                MainMenu mainmenu = new MainMenu();
                mainmenu.setVisible(true);
                mainmenu.setSize(500, 500);
                mainmenu.setLocationRelativeTo(null);
                registerInterface regFace = new registerInterface();
                regFace.setVisible(false);
                Login.this.dispose();
                Login.this.setVisible(false);
            }
        });

        jmiLogin.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                MainMenu mainmenu = new MainMenu();
                mainmenu.setVisible(true);
                mainmenu.setSize(500, 500);
                mainmenu.setLocationRelativeTo(null);
                registerInterface regFace = new registerInterface();
                regFace.setVisible(false);
                Login.this.dispose();
                Login.this.setVisible(false);
            }
        });
    }

    public static void main(String arg[]) {
        Login frame = new Login();
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}
class usernamecheck {

    static final String DATABASE_URL = "jdbc:mysql://localhost:3306/mysql";
    static final String USERNAME = "root";
    static final String PASSWORD = "root";


   // launch the application
    public static boolean checkLogin(String username, String password)
            throws SQLException {
        System.out.print("Running Check Login \n");

        Connection connection = null; // manages connection
        PreparedStatement pt = null; // manages prepared statement
        Statement stmt = null;
        String query="select userName from person where userName = ? and password = ?";


        // connect to database usernames and query database
        try {

            // establish connection to database
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            Connection con = DriverManager.getConnection(DATABASE_URL, "root", "root");

            // query database
            pt = con.prepareStatement("select userName from person where userName = ? and password = ?");
           
            // process query results
            pt.setString(1, username);
            ResultSet rs = pt.executeQuery(query);
            String orgUname = "", orPass = "";
            while (rs.next()) {
                orgUname = rs.getString("userName");
                orPass = rs.getString("password");
            } //end while
            if (orPass.equals(password) && orgUname.equals(username)) {
                //do something
                return false;
            } else {
                //do something
                return true;
            }
        }//end try
        catch (Exception e) {
        } //end catch  
        return true;
    } //end main
}
4

5 回答 5

2

Here is some advice:

Do NOT store passwords in the database. Store an MD5 hash of it, then have your Java code or Mysql function convert the user's password input text to an MD5 hash, and then compare that with what's stored in your person table.

Example using Java to do the hashing:

person table:

+----+------------+----------------------------------+
| id | username   | pwhash                           |
+----+------------+----------------------------------+
|  1 | bob        | 9ae4f6963062ba8c77db69aa1f821310 | 
|  2 | ryan       | 3f6af9632621a8ce7d00aa122e2d1310 | 
+----+------------+----------------------------------+

Java code:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

....

String username = ... // from UI input
String plaintext_password = ... // from UI input

String pwhash_from_passwd = makePwHash(username, plaintext_password);

String pwhash_from_db = ...   // SELECT pwhash FROM person WHERE userName=?

if (pwhash_from_db.equals(pw_hash_from_passwd)) {
    // user is authenticated
} else {
    // invalid username or password
}

...



protected static String makePwHash(String username, String plaintext_password) {
    MessageDigest mdigest=null;
    try {
        mdigest = MessageDigest.getInstance("MD5");
        String dbs = username + plaintext_password;
        byte mdbytes[] = mdigest.digest(dbs.getBytes());
        return toHexString(mdbytes);
    } catch (NoSuchAlgorithmException e) { }
    return null;
}



private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

/**
 * convert an array of bytes to an hexadecimal string
 * @return a string (length = 2 * b.length)
 * @param b bytes array to convert to a hexadecimal string
 */
public static String toHexString(byte b[]) {
    int pos = 0;
    char[] c = new char[b.length*2];
    for (int i=0; i< b.length; i++) {
        c[pos++] = toHex[(b[i] >> 4) & 0x0F];
        c[pos++] = toHex[b[i] & 0x0f];
    }
    return new String(c);
}
于 2013-09-27T18:21:32.900 回答
0

如果您输入不存在的用户和空密码,您的方法将返回 true。因此,在这种情况下,它不会阻止访问。为避免这种情况,您需要验证用户是否也存在。

这是一个例子。您可能不想完全这样做,但您应该明白这一点。

if (rs.next() && password.equals(rs.getString("password"))) {
    // do something
    return true;
} else {
    //do something
}

此外,当您从 调用该checkLogin方法时,ActionListener您并没有检查返回值,因此您并没有真正验证任何内容。你可以做这样的事情

if (usernamecheck.checkLogin(jtfUsername.getText(), jtfPassword.getText())) {
    // User validated
} else {
    // Not validated
}
于 2013-09-27T17:14:11.063 回答
0

提供密码=“”时我可以看到一个问题,在这种情况下将找不到记录,以下代码将返回 true

if (orPass.equals(password))  // when password =""
于 2013-09-27T17:14:20.047 回答
0

不是好的 JDBC 代码。我希望您不打算在生产中使用此代码。

这里只是它的许多错误中的一小部分:

  • 硬编码驱动程序、URL 和凭据。应设置在应用程序外部的连接池中。
  • 空捕获块。
  • 不关闭 Connection、Statement 或 ResultSet。
  • 任何应用程序都不应具有对数据库的 root 访问权限。您应该创建一个应用程序 ID 并仅授予完成任务所需的那些权限。
于 2013-09-27T18:00:05.217 回答
0

一些侧面观察:

1:下面的评论不正确,该功能不(或不应该)启动应用程序。它应该只验证用户名和密码并返回真/假。启动应用程序应该在它自己的函数中(一个函数应该做一件事)。

// 启动应用程序

public static boolean checkLogin(字符串用户名,字符串密码)

2:您应该使用 try/catch/finally 块来获取连接、preparedStatement 和 resultSet。然后在 finally 块中以相反的顺序关闭它们(首先检查 null),通常都在同一个函数中。

3:应使用连接池(dataSource),并且应用程序的数据源应在运行应用程序期间实现一次。使用池,应尽可能快地获得、使用和关闭(返回池)连接。

于 2013-09-27T18:49:36.003 回答