Не удалось подключиться к GTalk с помощью node.js и node-xmpp.

Я пытаюсь подключиться к GTalk, используя node.js и node-xmpp. Вместо успешного подключения node-xmpp возвращает ответ об ошибке XML.

Подготовка

$node -v
v0.10.24
$npm install node-stringprep
$npm install node-xmpp
$npm list
...
├─┬ [email protected]
...

gtalk.js

var xmpp = require('node-xmpp');
var sys = require("sys");

var options = {
    jid: "[email protected]",
    password: "mygooglepassword"
    //,host: "talk.google.com"
    //,port: 5222
};

var jabber = new xmpp.Client(options);

jabber.on('online', function() {
    console.log("Connected");
});

jabber.on('error', function(e) {
    sys.puts(e);
});

Ошибка

$node gtalk.js
<stream:error xmlns:stream="http://etherx.jabber.org/streams"><invalid-xml xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error>

Возможные объяснения

  1. Неправильный идентификатор/пароль (вход на веб-сайте Google работает)
  2. node-xmpp требуется хост/порт для подключения к GTalk (попробовал talk.google.com/5222)
  3. talk.google.com@5222 неверен (заголовок Google Doc Open Com говорит, что это правильно)
  4. GTalk разрешает только OAuth2 (Google Doc Open Com говорит, что SASL PLAIN разрешен для «устаревших» устройств)
  5. Это то же самое, что и StackOverflow#4349577 (нет такой же опечатки)
  6. Я неправильно использую node-xmpp
  7. GTalk не отвечает должным образом
  8. node-xmpp содержит ошибки/не поддерживает GTalk

Я почти уверен, что исключаю 1-5, и я был бы рад услышать другие объяснения или доказательства для 6-8. Спасибо!

Обновления

<сильный>1. Поток XML ("=>" исходящий, "‹=" входящий)

=> <stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" to="gmail.com">
<= <stream:stream from="gmail.com" id="C2AA8A4648B596A1" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client"><stream:features><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism></mechanisms></stream:features>
=> <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
<= <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
=> <stream:stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" to="gmail.com">
<= <stream:stream from="gmail.com" id="3D42C6DC5985A9E6" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
<= <stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>X-OAUTH2</mechanism><mechanism>X-GOOGLE-TOKEN</mechanism><mechanism>PLAIN</mechanism></mechanisms></stream:features>
=> <auth auth:service="oauth2" xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-OAUTH2">AGNvaW2iaXRzeUBnbWFpbC5jb12AdW5kZWZpbmVk</auth>
<= <stream:error><invalid-xml xmlns="urn:ietf:params:xml:ns:xmpp-streams"/></stream:error>

Кажется, node-xmpp пытается использовать OAUTH2, хотя я вообще не предоставил никакого токена. Вместо этого следует использовать PLAIN.

<сильный>2. пример node-xmpp oauth тоже не работает

Создан токен OAUTH2 в соответствии с запросом на вытягивание node-xmpp #85.

$node node_modules/node_xmpp/examples/echo_bot_oauth.js [email protected] oauth2token
No usable SASL mechanism

<сильный>3. Добавление preferred:"PLAIN" устраняет проблему с подключением

изменение параметров на

 var options = {
   jid: "[email protected]",
   password: "mygooglepassword",
   preferred: "PLAIN"
 };

исправляет ошибку и, похоже, успешно аутентифицируется. Это может свидетельствовать об объяснении №8 (ошибка в node-xmpp).


person InteractiveCube    schedule 22.01.2014    source источник
comment
Ошибка предполагает, что вы каким-то образом отправляете синтаксически недопустимый XML. Не могли бы вы получить информацию о том, что на самом деле отправляется на сервер? Не уверен, как это сделать с помощью node-xmpp, но tcpdump или Wireshark могут помочь.   -  person legoscia    schedule 22.01.2014
comment
Обновлен захваченный поток XML, похоже, что node-xmpp пытается аутентифицироваться с помощью oauth2, но GTalk это не нравится?   -  person InteractiveCube    schedule 22.01.2014


Ответы (2)


XML, который вы отправляете, действительно недействителен:

<auth auth:service="oauth2"
      xmlns="urn:ietf:params:xml:ns:xmpp-sasl"
      mechanism="X-OAUTH2">
  ...
</auth>

Он использует префикс пространства имен auth, нигде его не определяя.

В описании Google авторизации OAuth есть пример, включающий объявление пространства имен (атрибут xmlns:auth):

<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl"
    mechanism="X-OAUTH2"
    auth:service="oauth2"
    xmlns:auth="http://www.google.com/talk/protocol/auth">
  base64("\0" + user_name + "\0" + oauth_token)
</auth>

Так что об этом, вероятно, следует сообщить разработчикам node-xmpp как об ошибке.

person legoscia    schedule 22.01.2014
comment
xmlns:auth действительно отсутствует; однако в первую очередь не следует использовать OAuth2. Понятия не имею, как был сгенерирован токен, который он использует. Итак, это указывает на объяснение № 8, и я должен отправить отчет об ошибке? - person InteractiveCube; 22.01.2014
comment
Должна быть опция, позволяющая предпочесть PLAIN аутентификацию, хотя я не смог найти ее с помощью быстрого поиска в Google. - person legoscia; 22.01.2014

Это ошибка в node-xmpp, появившаяся в 0.10.9.

person InteractiveCube    schedule 23.01.2014