如何使用 smack 库从客户端搜索 ejabberd 服务器上的注册用户?

Posted

技术标签:

【中文标题】如何使用 smack 库从客户端搜索 ejabberd 服务器上的注册用户?【英文标题】:How to search registered user on ejabberd server from client side using smack library? 【发布时间】:2020-08-20 07:01:13 【问题描述】:

我在客户端使用 smack。我尝试在客户端搜索注册用户,因为在创建新用户之前,我想知道该 ID 是否已在服务器上注册,如果没有,则创建用户要么登录用户,但 ejabberd 服务器因错误而崩溃。这是ejabberd服务器的崩溃日志。

Failed to process iq:
#iq
 id = <<"Hh6AJ-28">>,type = set,lang = <<"en">>,
 from =
  #jid
   user = <<"admin">>,server = <<"faiqkhan-virtualbox">>,
   resource = <<"92526029764259513741138">>,luser = <<"admin">>,
   lserver = <<"faiqkhan-virtualbox">>,
   lresource = <<"92526029764259513741138">>,
 to =
  #jid
   user = <<>>,server = <<"vjud.faiqkhan-virtualbox">>,resource = <<>>,
   luser = <<>>,lserver = <<"vjud.faiqkhan-virtualbox">>,lresource = <<>>,
 sub_els =
  [#xmlel
    name = <<"query">>,
    attrs = [<<"xmlns">>,<<"jabber:iq:search">>],
    children =
     [#xmlel
       name = <<"x">>,
       attrs = [<<"xmlns">>,<<"jabber:x:data">>,<<"type">>,<<"submit">>],
       children =
        [#xmlel
          name = <<"field">>,
          attrs = [<<"var">>,<<"user">>,<<"type">>,<<"text-single">>],
          children =
           [#xmlel
             name = <<"value">>,attrs = [],
             children = [xmlcdata,<<"wasiq@faiqkhan-virtualbox">>]]]]],
 meta = #ip => 0,0,0,0,0,65535,49320,11092
exception error: module_not_loaded,mod_vcard_mnesia,
                                     <<"faiqkhan-virtualbox">>
   in function  gen_mod:get_module_opts/2 (src/gen_mod.erl, line 338)
   in call from gen_mod:get_module_opt/3 (src/gen_mod.erl, line 318)
   in call from mod_vcard_mnesia:filter_fields/3 (src/mod_vcard_mnesia.erl, line 200)
   in call from mod_vcard_mnesia:search/4 (src/mod_vcard_mnesia.erl, line 78)
   in call from mod_vcard:search_result/4 (src/mod_vcard.erl, line 479)
   in call from mod_vcard:process_search/1 (src/mod_vcard.erl, line 264)
   in call from gen_iq_handler:process_iq/3 (src/gen_iq_handler.erl, line 131)
   in call from gen_iq_handler:process_iq/4 (src/gen_iq_handler.erl, line 109)

我使用以下代码从客户端获取注册用户:

InetAddress address = InetAddress.getByName(HOST);
DomainBareJid serviceName = JidCreate.domainBareFrom("faiqkhan-VirtualBox");        XMPPTCPConnectionConfiguration.Builder builder = XMPPTCPConnectionConfiguration.builder();
builder.setPort(PORT);
builder.setSendPresence(true);
builder.setHostAddress(address);
builder.setServiceName(serviceName);
builder.setUsernameAndPassword("admin", "123456");
builder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
XMPPTCPConnection connection = new XMPPTCPConnection(builder.build());
try 
    connection.connect();
    connection.login("admin", "123456");
    Logger.showError("21560-connection created to: " + connection.getHost());
    Roster roster = Roster.getInstanceFor(connection);
    Set<RosterEntry> entities = roster.getEntries();
    UserSearchManager search = new UserSearchManager(connection);
    DomainBareJid s = JidCreate.domainBareFrom("vjud.".concat("faiqkhan-VirtualBox"));
    Form searchForm = search.getSearchForm(s);
    Form answerForm = searchForm.createAnswerForm();
    answerForm.setAnswer("user", "wasiq@faiqkhan-virtualbox");
    ReportedData data = search.getSearchResults(answerForm, s);
    if (data.getRows() != null) 
        for (ReportedData.Row row : data.getRows()) 
            for (CharSequence value : row.getValues("jid")) 
                Log.i("Iteartor values......", " " + value);
            
        
    

     catch (SmackException | IOException | XMPPException | InterruptedException e) 
        Logger.showError("21560-error on account creation: " + e.getMessage());
    

服务器在ReportedData data = search.getSearchResults(answerForm, s); 代码行崩溃。

【问题讨论】:

【参考方案1】:

您在 ejabberd 中发现了一个错误:

    已经在 2018 年修复 https://github.com/processone/ejabberd/commit/1be21126342d503205798605725ba5ceef9de42b 但该错误在 2019 年重新引入 https://github.com/processone/ejabberd/commit/a02cff0e780bb735531594c4ece81e8628f79782#diff-71f613241ed580c3e5dad2b4526503f2R12 我现在在 https://github.com/processone/ejabberd/commit/92913389a51ddc564f11e0712b0d82fca8c9aecb

但即使修复了该错误,您想要使用的功能也可能无济于事:用户必须设置他的 vCard 才能在 vJud 搜索中提供他的帐户。换句话说,vJUD 在存储的 vCard 中搜索,而不是在注册帐户中搜索。如果我注册了一个账号但没有设置vCard,那么vJUD就找不到了。

在创建新用户之前,我想知道该 id 是否已在服务器上注册

您为什么不先尝试注册帐户?

另一方面,如果您想提前检查一个帐户是否可以注册(就像一些网络注册网站那样,允许用户修改用户名,直到有一个可用),那么我认为 XMPP出于安全原因,不提供这种可能性:不允许知道帐户是否存在。

解决方案是使用 check_account ejabberd 命令 https://docs.ejabberd.im/developer/ejabberd-api/admin-api/#check-account 使用一些前端执行它,例如 ejabberdctl、ReST 或 XMLRPC https://docs.ejabberd.im/admin/guide/managing/#ejabberd-commands

$ ejabberdctl check_account user1 localhost
$ ejabberdctl check_account user6666 localhost
Error: false
~ 1

【讨论】:

是的,我正在注册使用。如果我在注册时遇到重复的 id 异常,我只需登录用户即可。

以上是关于如何使用 smack 库从客户端搜索 ejabberd 服务器上的注册用户?的主要内容,如果未能解决你的问题,请参考以下文章

无法打开 ejabbered Web 仪表板 localhost:5280

不能在 XMPP 服务器上加入/创建超过 10 个组

如何使用 Smack 从 android 客户端获取 openfire 在线注册用户?

如何让客户了解 Smack 中的新 HostedRoom?

如何使用 SMACK 在 Android XMPP 客户端中解析自定义花名册查询响应

如何在 Openfire 中使用 smack