10

我需要从 PHP 脚本创建一个 ejabberd 用户。我还需要能够将新用户添加到预定义的共享名册中。

我应该调用ejabberdctlusingexec()还是有更好的方法?

4

7 回答 7

10

这是我的最终解决方案:

感谢jldupont 的建议,这ejabberdctl将是最简单的解决方案,我克服了遇到的障碍并找到了可行的解决方案。

默认情况下,apache 的用户没有正确的权限来成功运行ejabberdctl(并且有充分的理由)。所以为了让它工作,你必须用sudo. 但是...sudo需要密码,这会带来两个问题:

  1. apache 用户没有密码。
  2. 即使这样做了,也无法从 PHP 中输​​入它。

解决方案(适用于 Ubuntu) - 在末尾添加这一行/etc/sudoers

www-data ALL= (ejabberd) NOPASSWD: /usr/sbin/ejabberdctl

sudoers 文件和 ejabberdctl 的路径可能因其他 Linux 发行版而异。这允许 apache 的用户 ( www-data) 仅以ejabberdctl提升的权限运行且无需密码。

剩下的就是 PHP 代码:

<?php
    $username = 'tester';
    $password = 'testerspassword';
    $node = 'myserver.com';
    exec('sudo -u ejabberd /usr/sbin/ejabberdctl register '.$username.' '.$node.' '.$password.' 2>&1',$output,$status);
    if($output == 0)
    {
        // Success!
    }
    else
    {
        // Failure, $output has the details
        echo '<pre>';
        foreach($output as $o)
        {
            echo $o."\n";
        }
        echo '</pre>';
    }
?>

安全

重要的是要注意,即使您只允许一个命令由www-data. 如果您使用这种方法,您需要确保在某种身份验证之后保护 PHP 代码,以便不只是任何人都可以使其执行。除了明显的安全风险外,它还可能使您的服务器遭受拒绝服务攻击。

于 2009-10-27T20:52:47.183 回答
7

我在 2016 年遇到了这个问题,有比公认的答案和投票最高的答案更容易实现的方法。

  1. 使用 XMPP PHP 库,最常见的是:

https://github.com/fabiang/xmpp

  1. 虽然此库不支持开箱即用添加用户,但您可以非常轻松地扩展它

这是我为添加用户编写的类:

use Fabiang\Xmpp\Util\XML;

/**
 * Register new user
 * @param string $username
 * @param string $password
 * @param string $email
 * @package XMPP\Protocol
 * @category XMPP
 */
class Register implements ProtocolImplementationInterface
{  
    protected $username;
    protected $password;
    protected $email;

    /**
     * Constructor.
     *
     * @param string $username
     * @param string $password
     * @param string $email
     */
    public function __construct($username, $password, $email)
    {
        $this->username = $username;
        $this->password = $password;
        $this->email = $email;
    }

    /**
     * Build XML message
     * @return type
     */
    public function toString()
    {
        $query = "<iq type='set' id='%s'><query xmlns='jabber:iq:register'><username>%s</username><password>%s</password><email>%s</email></query></iq>";        
        return XML::quoteMessage($query, XML::generateId(), (string) $this->username, (string) $this->password, (string) $this->email);
    }
}
  1. 您必须在 ejabberd.cfg 文件中启用带内注册,因为默认情况下它被拒绝:

{访问,注册,[{允许,全部}]}。

最后是使用这个类的示例代码:

private function registerChatUser($name, $password, $email)
    {       
        $address = 'tcp://yourserverip:5222';
        $adminUsername = 'youradmin';
        $adminPassword = 'youradminpassword';

        $options = new Options($address);
        $options->setUsername($adminUsername)->setPassword($adminPassword);

        $client = new Client($options);         
        $client->connect();             

        $register = new Register($name, $password, $email);                 
        $client->send($register);   

        $client->disconnect();
    }

如果服务器没有有效的 SSL 证书,库调用将失败。放置一个有效的证书,或者用下面的代码片段替换 SocketClient.php 中的这个部分

// call stream_socket_client with custom error handler enabled
$handler = new ErrorHandler(
    function ($address, $timeout, $flags) {
        $options = [
            'ssl' => [
                'allow_self_signed' => true,
                'verify_peer_name' => false,
            ],
        ];
        $context = stream_context_create($options);
        return stream_socket_client($address, $errno, $errstr, $timeout, $flags, $context);
    },
    $this->address,
    $timeout,
    $flags
);
于 2016-01-29T18:35:59.323 回答
4

在这种特定情况下,ejabberdctl 是迄今为止最简单的。其他选项是:

  • 用 PHP 实现一个完整的客户端 XMPP (!)

  • 在 Erlang 中实现一个代理请求的模块:PHP<-->Erlang 通信需要通过套接字,并且会涉及大量编组(!)

于 2009-10-26T19:42:32.787 回答
1

如果您想要在 XMPP 协议中使用 PHP 以一种干净且安全的方式执行此操作,我建议您使用此示例脚本register_user.php。这是一个可以在Jaxl PHP 库中找到的示例。

下载 Jaxl 库并使用如下:

JAXL $ php examples/register_user.php localhost
Choose a username and password to register with this server
username:test_user
password:test_pass
registration successful
shutting down...
JAXL $
于 2012-10-02T19:37:01.603 回答
0

最简单的方法是使用 mod_xmlrpc - 它允许您使用 xmlrpc 运行 ejabberdctl 命令。这很容易与以下库一起使用:

https://github.com/gamenet/php-jabber-rpc

/* Add user to Jabber */
use \GameNet\Jabber\RpcClient;
use \GameNet\Jabber\Mixins\UserTrait;
$rpc = new RpcClient([
        'server' => 'jabber.org:4560',
        'host' => 'myhost.org',
        'debug' => false,
    ]);

$result=$rpc->createUser( $username, $password );
于 2015-04-06T18:26:51.390 回答
0

我已经用mod_register_web [ 1 , 2 ] 解决了这个问题。它不需要大量代码,而且我认为它足够安全。mod_register_web 提供带有简单 POST 表单的 html 页面来注册新用户。

在单独的 http 侦听器下启用模块(在我的情况下,端口 5281)。使此端口仅可用于带有“ip”参数的本地请求。

listen:
  port: 5280
  module: ejabberd_http
  web_admin: true
  http_bind: true
  ## register: true

ip: "127.0.0.1"   # Only local requests allowed for user registration
  port: 5281
  module: ejabberd_http
  register: true

modules:
  mod_register_web: {}

请求示例:

curl -XPOST 127.0.0.1:5281/register/new -d 'username=lucky&host=vHost&password=test&password2=test'

可以使用适当的库(已经在我的框架中)从 php 代码执行请求。

于 2016-02-27T12:53:23.190 回答
0
curl -XPOST 127.0.0.1:5281/api/register -d '{"user":"lucky","host":"data.com","password":"test"}'

要申请 php,您可以使用标准 curl ,上面的代码是未发布的 ejabberd 文档中包含的最新 curl 代码,

我只是应用它并从 doc ejabber 分析它,然后将其调整为在 ejabberd config xml 上创建的 ejabberd url 路径

于 2017-02-06T16:41:21.173 回答