Java 使用JDBC实现gui的用户名和密码检查,但是

Java 使用JDBC实现gui的用户名和密码检查,但是,java,mysql,jdbc,Java,Mysql,Jdbc,我使用JDBC检查数据库中的用户名和密码,以授予对gui的登录访问权限,但当我尝试测试JDBC是否正常工作时,如果输入了错误的用户名和密码,它不会阻止访问 如果输入不存在的用户和空密码,则方法将返回true。因此,在这种情况下,它不会阻止访问。为了避免这种情况,您需要验证用户是否也存在 这里有一个例子。你可能不想这样做,但你应该有这个想法 if (rs.next() && password.equals(rs.getString("password"))) { // do

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

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

这里有一个例子。你可能不想这样做,但你应该有这个想法

if (rs.next() && password.equals(rs.getString("password"))) {
    // do something
    return true;
} else {
    //do something
}
另外,当您从
ActionListener
调用
checkLogin
方法时,您没有检查返回值,因此没有真正验证任何内容。你可以这样做

if (usernamecheck.checkLogin(jtfUsername.getText(), jtfPassword.getText())) {
    // User validated
} else {
    // Not validated
}

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

if (orPass.equals(password))  // when password =""
这不是好的JDBC代码。我希望您不打算在生产中使用此代码

以下是许多问题中的一些:

  • 硬编码驱动程序、URL和凭据。应在应用程序外部的连接池中设置
  • 空挡块
  • 不关闭连接、语句或结果集
  • 任何应用程序都不应具有对数据库的根访问权限。您应该创建应用程序ID并仅授予完成任务所需的权限
    • 以下是一些建议:

      不要在数据库中存储密码。存储它的MD5散列,然后让Java代码或Mysql函数将用户的密码输入文本转换为MD5散列,然后将其与
      person
      表中存储的内容进行比较

      使用Java进行散列的示例:

      人员
      表格:

      +----+------------+----------------------------------+
      | id | username   | pwhash                           |
      +----+------------+----------------------------------+
      |  1 | bob        | 9ae4f6963062ba8c77db69aa1f821310 | 
      |  2 | ryan       | 3f6af9632621a8ce7d00aa122e2d1310 | 
      +----+------------+----------------------------------+
      
      Java代码:

      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);
      }
      
      import java.security.MessageDigest;
      导入java.security.NoSuchAlgorithmException;
      ....
      字符串用户名=…//从用户界面输入
      字符串明文密码=…//从用户界面输入
      字符串pwhash_from_passwd=makePwHash(用户名、明文密码);
      字符串pwhash_from_db=…/从userName=?
      if(pwhash_from_db.equals(pwhash_from_passwd)){
      //用户已通过身份验证
      }否则{
      //无效的用户名或密码
      }
      ...
      受保护的静态字符串makePwHash(字符串用户名、字符串明文\u密码){
      MessageDigest mdigest=null;
      试一试{
      mdigest=MessageDigest.getInstance(“MD5”);
      字符串dbs=用户名+明文密码;
      字节mdbytes[]=mdigest.digest(dbs.getBytes());
      返回到hextstring(mdbytes);
      }catch(nosuchalgorithme){}
      返回null;
      }
      私有静态最终字符[]toHex={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
      /**
      *将字节数组转换为十六进制字符串
      *@返回字符串(长度=2*b.length)
      *@param b bytes数组转换为十六进制字符串
      */
      公共静态字符串到十六进制字符串(字节b[]{
      int pos=0;
      char[]c=新字符[b.长度*2];
      for(int i=0;i>4)&0x0F];
      c[pos++]=toHex[b[i]&0x0f];
      }
      返回新字符串(c);
      }
      
      一些侧面观察:

      1:下面的注释不正确,函数没有(或不应该)启动应用程序。它应该只验证用户名和密码,并返回true/false。 启动应用程序应该在它自己的函数中(函数应该做一件事)

      //启动应用程序

      公共静态布尔checkLogin(字符串用户名、字符串密码)

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


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

      吞咽异常不是一种好的做法。此代码看起来工作正常(除了可以使用
      if(rs.next()
      而不是
      while
      )。您的问题可能是如何向用户展示GUI。@LuiggiMendoza用我的GUI更新了代码。如果(或密码等于)或用户名等于,这行代码是什么{当它们都相等时,您返回false,是不是应该是另一种方式???@SachinThapa我正在切换它们,看看它们是否会改变什么,它们一开始是真的,但我没有看到任何变化..因此添加
      orgUname.equals(用户名)
      if语句解决了这个问题?实际上,有人可以使用空用户名和空密码登录。不好。你可以检查数据库查询是否确实返回了一些内容。如果它返回0行,那么用户就不存在。如果你能给我举个例子,那就太好了,我完全迷路了,我马上就要说了t并尝试明天完成它。为这个例子干杯,这样就允许具有匹配密码的用户访问?阿门,兄弟。+1。值得一提的还有盐渍。谢谢你,我可能会在解决当前问题后实现这个。