从PHP创建ejabberd用户

时间:2009-10-26 19:37:37

标签: php xmpp ejabberd

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

我应该使用ejabberdctl拨打exec()还是有更好的方式?

7 个答案:

答案 0 :(得分:10)

这是我的最终解决方案:

感谢jldupont's advice ejabberdctl是最简单的解决方案,我抓住了遇到的障碍并找到了有效的解决方案。

默认情况下,apache的用户没有成功运行ejabberdctl的权限(并且有充分的理由)。因此,为了使其正常工作,您必须使用sudo进行调用。但是...... sudo需要一个密码,这会产生两个问题:

  1. apache用户没有密码。
  2. 即使它确实如此,也无法从PHP输入。
  3. 解决方案(对于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代码,这样不仅任何人都可以执行它。除了明显的安全风险之外,它还可能使您的服务器遭受拒绝服务攻击。

答案 1 :(得分:6)

我在2016年遇到了这个问题,实现这个问题的方法比接受的答案和最高的答案要容易得多。

  1. 使用XMPP PHP库,最常见的是:
  2. https://github.com/fabiang/xmpp

    1. 虽然这个图书馆不支持添加开箱即用的用户,但您可以非常轻松地扩展它
    2. 这是我为添加用户而写的课程:

      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文件中启用带内注册,因为它默认被拒绝:
      2.   

        {access,register,[{allow,all}]}。

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

        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
        );
        

答案 2 :(得分:4)

到目前为止,ejabberdctl在这个具体案例中是最简单的。其他选项是:

  • 在PHP中实现完整的客户端XMPP(!)

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

答案 3 :(得分: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 $

答案 4 :(得分: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 );

答案 5 :(得分:0)

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

在单独的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代码执行请求。

答案 6 :(得分:0)

curl -XPOST 127.0.0.1:5281/api/register -d'{“user”:“lucky”,“host”:“data.com”,“password”:“test”}'