Создайте пользователя ejabberd из PHP


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

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

Author: BoltClock, 2009-10-26

7 answers

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

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

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

 4
Author: jldupont, 2009-10-26 19:42:32

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

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

По умолчанию пользователь apache не имеет прав доступа для успешного запуска ejabberdctl (и по уважительной причине). Поэтому для того, чтобы он работал, вы должны вызвать его с помощью sudo. Но... sudo требуется пароль, что создает 2 проблемы:

  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-код с помощью какой-либо аутентификации, чтобы не только кто-либо мог заставить его выполняться. Помимо очевидных угроз безопасности, это может открыть ваш сервер для атаки типа "Отказ в обслуживании".

 10
Author: Andrew Ensley, 2017-05-23 12:24:23

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

  1. Используйте PHP-библиотеку XMPP, наиболее распространенной из которых является:

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
);
 6
Author: Amr H. Abd Elmajeed, 2016-01-29 18:35:59

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

Загрузите библиотеку 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 $
 1
Author: Abhinav Singh, 2012-10-02 19:37:01

Самый простой способ сделать это - использовать 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 );
 0
Author: richp10, 2015-04-06 18:26:51

Я решил проблему с помощью mod_register_web [1, 2]. Это не требует тонны кода и, я думаю, достаточно безопасно. mod_register_web предоставляет 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-кода с соответствующей библиотекой (которая уже была в моей структуре).

 0
Author: serkas, 2016-02-27 13:13:28

Curl -XPOST 127.0.0.1:5281/api/register -d'{"пользователь": "счастливчик", "хост":"data.com ", "пароль": "тест"}'

 0
Author: Fikalefaza, 2017-02-06 16:41:21