如何使用 Smack XMPP API 处理(失败的)登录尝试

Posted

技术标签:

【中文标题】如何使用 Smack XMPP API 处理(失败的)登录尝试【英文标题】:How to handle (failed) login attempts with Smack XMPP API 【发布时间】:2013-03-28 00:48:48 【问题描述】:

我正在开发一个基于 XMPP 和 Smack API 的聊天服务器,它连接到一个 Openfire 服务器(由一个和我一起开发的朋友托管)。

所以,我几天前才开始编程(OS X 10.8 上的 Netbeans),今天我继续进行连接和登录方面的工作。

我可以通过正确选择用户名+密码完美登录:P 但我不知道如何处理无效登录尝试并让应用显示一条消息,然后允许用户重试。

这是我的代码,在用户按下我的 Swing JForm 中的按钮后触发:

(注意:XMPPConnection 对象已在另一个类中创建,并且已与服务器建立连接。您可以看到我正在从另一个类中调用该对象)

private void btnIniciarSesionActionPerformed(java.awt.event.ActionEvent evt)                                                  
    String Usuario = txtUsuario.getText();
    String Password = new String (pwdContrasena.getPassword());

    if (Usuario.equals("") || Password.equals(""))
        // Missing data
        JOptionPane.showMessageDialog(null, "Missing data");
    
    else
        //Try to login
        try
            Proyecto_chat.conexion.login(Usuario, Password, "x");
        
        catch (XMPPException ex)
            Logger.getLogger(Ventana_login.class.getName()).log(Level.SEVERE, null, ex);
            // Problem
        
        if (Proyecto_chat.conexion.isAuthenticated() == true)  //Login has been successful
            jLabel1.setVisible(false);
            System.out.println("Authenticated as " + Usuario);
            JOptionPane.showMessageDialog(null, "Authenticated as " + Usuario);
            //Exit login window and carry on  
        
        else
            JOptionPane.showMessageDialog(null, "login error");
        
    

我应该玩我得到的那个例外吗? ->

SEVERE: null
SASL authentication DIGEST-MD5 failed: not-authorized: 
at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:337)
at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:203)
at proyecto_chat.Ventana_login.btnIniciarSesionActionPerformed(Ventana_login.java:159)
at proyecto_chat.Ventana_login.access$100(Ventana_login.java:15)
at proyecto_chat.Ventana_login$2.actionPerformed(Ventana_login.java:73)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
(...) more lines that I think are not critical for this

由于密码以纯文本形式存储(大学项目,所以没关系)以简化从应用程序内部更改密码,我可以从客户端计算机连接到数据库(远程服务器中的 PostgreSQL),并检查密码,并且仅在用户和密码匹配时才执行“conexion.login”,但那将是……你知道……错误

在网上看了一圈后没有运气,我决定去这里问问,睡觉,第二天早上醒来,提出一些建议;) 帮助将不胜感激

【问题讨论】:

【参考方案1】:

不确定我是否理解您的问题,但如果是“我如何确定使用 Smack 登录尝试失败的原因?”那么这是我的答案:

如果您想确定登录失败的原因,您必须从 Smack 3.2.2 开始评估 (XMPP)Exception 的消息字符串。这些区分各种失败原因的消息字符串目前在源代码中是硬编码的,这通常不是一个好主意。

不久前我创建了SMACK-416 "Improve Exceptions on connect() and login()" 来解决这个问题。这个想法是用类层次结构替换硬编码的字符串/失败原因。但它肯定需要几个月的时间才能实施(可能需要几周/几个月/几年才能发布)。

【讨论】:

其实,主要问题是当我尝试使用无效的用户名/密码登录时,抛出了一些异常(以及我设置的信息显示),但应用程序不会让我再次登录(好像我更正了数据并再次单击按钮)。我终于通过将.connect() 放在.login() 方法后面来解决这个问题,并在登录错误的情况下调用.disconnect(),因此每次用户尝试登录时都会重新连接服务器 如果这些功能在连接失败等方面实际上更“冗长”,那就太好了;)【参考方案2】:

实际上,主要问题是当我尝试使用无效的用户名/密码登录时,抛出了一些异常(以及我设置的信息显示),但应用程序不允许我再次登录(好像我更正了我的数据并再次单击了按钮)。

我终于解决了这个问题,将 .connect() 放在 .login() 方法后面,并在登录失败时调用 .disconnect() ,因此每次用户尝试登录时都会重新连接服务器在。

这可能不是理想的方法,但我发现它既简单又可行。感谢您的帮助!

【讨论】:

数据库中不存在用户名和密码的错误如何处理 @DeclanNnadozie 这个帖子是 2013 年的,我什么都不记得了。您最好发布一个新问题,有人可能会提供帮助

以上是关于如何使用 Smack XMPP API 处理(失败的)登录尝试的主要内容,如果未能解决你的问题,请参考以下文章

Xmpp 连接因 smack 失败

SMACK API 带内注册失败并出现禁止错误

如何在 java 中使用 Smack XMPP 库处理 TLS 证书

XMPP 注销(Smack API)

使用 Smack API (xmpp) 从 Java 回调 JavaFX

当使用 Smack 4.1.0 API 作为 Google 的 GCM CCS 的 XMPP 客户端时,SecurityMode.required 不起作用