在 Ejabberd/XMPP 中禁止用户同时从多个设备登录

Disable user login from multiple devices at the sametime, in Ejabberd/XMPP

Environment:

Ejabberd Version : 16.04

Smack-android-4.1.0

我正在开发 Android 聊天应用程序。目前,可以使用相同的用户凭据从多个设备登录。

当前场景如下:

1. User logs in into the app in device A
2. Using the same username and password, the user logs successfully into the app in device B
3. Now device A says, it is disconnected, but continue the chat in device B

但是,根据给定的要求,它应该是这样的:

1. User logs in into the app in device A
2. Using the same username and password, when the user tries to log in from device B, it should not allow it. 
(Since he is already logged in from device A)

很高兴听到您的 solutions/ideas 意见。提前致谢。

如果设备B设置为与设备A不同的资源一,两者都可以正确连接到同一个帐户。在您的测试中,设备 B 设置了与设备 A 完全相同的资源,然后 ejabberd 启动旧会话。

我看到有一个选项可以限制帐户在服务器中可以激活的会话数。问题是它会启动旧会话,但您想禁止新登录。看 https://docs.ejabberd.im/admin/configuration/#limiting-opened-sessions-with-acl

来自 XMPP 规范:

"If there is already an active resource of the same name, the server MUST either (1) terminate the active resource and allow the newly-requested session, or (2) disallow the newly-requested session and maintain the active resource. Which of these the server does is up to the implementation, although it is RECOMMENDED to implement case #1."

更多信息在这里https://xmpp.org/rfcs/rfc3921.html#session

所以您当前的场景是推荐的。

但是,我很快检查了 ejabberd 源代码,发现它可以以某种方式配置(closeold -> closenew)

https://github.com/processone/ejabberd/blob/master/src/ejabberd_c2s.erl#L964

https://github.com/processone/ejabberd/blob/master/src/ejabberd_c2s.erl#L873

我不是Erlang专家,不过貌似可以通过修改源码实现

所以我设法使用选项 resource_conflict

解决了问题

根据Ejabberd Configuring Docs

The option resource_conflict defines the action when a client attempts to login to an account with a resource that is already connected. The option syntax is:

resource_conflict: setresource|closenew|closeold: The possible values match exactly the three possibilities described in XMPP Core: section 7.7.2.2. The default value is closeold. If the client uses old Jabber Non-SASL authentication (XEP-0078), then this option is not respected, and the action performed is closeold.

因此打开 ejabberd.yml 并将以下行添加到该文件。

resource_conflict: closenew 

然后重启ejabberd服务器。

现在它将禁止新连接客户端的资源绑定尝试,并保持当前连接客户端的会话。

参考文献:

  1. https://www.rfc-editor.org/rfc/rfc6120#section-7.7.2.2
  2. 阅读@rubycon 对此的回答-