Вопрос

Мне нужно создать пользователя ejabberd из PHP-скрипта.Мне также нужно иметь возможность добавить нового пользователя в предопределенный общий список.

Должен ли я просто позвонить ejabberdctl с использованием exec() или есть лучший способ?

Это было полезно?

Решение

ejabberdctl в данном конкретном случае, безусловно, самый простой вариант.Другие варианты:

  • Реализуйте полноценный клиентский XMPP на PHP (!)

  • Реализуйте модуль в Erlang, который проксирует запросы:связь PHP<-->Erlang должна осуществляться через сокет, и потребуется много маршалинга (!)

Другие советы

Вот мое окончательное решение:

Благодаря совету jldupont о том, что ejabberdctl будет Самое простое решение - я преодолел все препятствия, с которыми столкнулся, и нашел рабочее решение.

По умолчанию пользователь apache не имеет необходимых прав для успешного запуска sudo (и по уважительной причине). Таким образом, чтобы это работало, вам нужно вызвать его с помощью /etc/sudoers. Но ... www-data требуется пароль, который представляет две проблемы:

<Ол>
  • У пользователя apache нет пароля.
  • Даже если это так, нет способа ввести его из PHP.
  • Решение (для Ubuntu) - добавьте эту строку в конце <=>:

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

    Путь к файлу sudoers и ejabberdctl может отличаться для других дистрибутивов Linux. Это позволяет пользователю apache (<=>) запускать только <=> с повышенными привилегиями и без пароля.

    Осталось только код 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>';
        }
    ?>
    

    Безопасность

    Важно отметить, что это представляет значительную угрозу безопасности, даже если вы разрешаете <=> запускать только одну команду. Если вы используете этот подход, вам необходимо убедиться, что вы защищаете код PHP за своего рода аутентификацией, чтобы его мог выполнить не только кто-либо. Помимо очевидных угроз безопасности, он может открыть ваш сервер для атаки отказ в обслуживании.

    Я столкнулся с этим вопросом в 2016 году, есть гораздо более простые способы его реализации, чем принятый ответ и самый высокий голос.

    <Ол>
  • Используйте библиотеку XMPP PHP, наиболее распространенной из которых является
  • 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.   

        {доступ, регистрация, [{разрешить, все}]}.

        Наконец, вот пример кода для использования этого класса:

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

    Если вам нужен чистый и безопасный способ сделать это с использованием PHP в протоколе XMPP, я рекомендую работать с этим примером сценария register_user.php . Это пример, который можно найти в Jaxl PHP Library.

    Загрузите библиотеку 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 $
    

    Самый простой способ сделать это - использовать mod_xmlrpc, который позволяет вам запускать команды ejabberdctl, используя xmlrpc. Это легко использовать с такой библиотекой, как:

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

    Я решил проблему с помощью mod_register_web [ 1 , 2 ]. Это не требует тонны кода и, я думаю, достаточно безопасно. mod_register_web предоставляет html-страницу с простой формой POST для регистрации нового пользователя.

    Включить модуль в отдельном прослушивателе http (в моем случае, порт 5281). Сделайте этот порт доступным только для локальных запросов с & Quot; ip & Quot; параметр.

    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 с соответствующей библиотекой (которая уже была в моей структуре).

    curl -XPOST 127.0.0.1:5281/api/register -d '{" пользователь ": " lucky ", " host < !> Quot;:! & Quot; data.com <> Quot;, <> Quot; пароль <> Quot;:! & Quot; тест <> Quot;}

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top