Компания
942,28
рейтинг
10 мая 2011 в 12:37

Разное → Поддержка протокола XMPP в Mail.Ru Агенте и «секреты» авторизации на XMPP-сервере Facebook

Мы рады сообщить вам о выходе Mail.Ru Агента версии 5.8 для Windows!

Главная «фича» этой версии – поддержка протокола XMPP (Jabber), которая ранее уже появилась в мобильных клиентах для платформ Symbian и Java 2 Micro Edition. Поскольку мобильным мессаджингом пользуется наиболее активная и технически «продвинутая» часть нашей аудитории, эксперимент с XMPP мы начали именно с мобильных платформ. Однако «фича» неожиданно оказалась довольно популярной и востребованной, в том числе, и на десктопе.

Основная идея поддержки этого протокола заключается в том, чтобы сделать возможным обмен IM-сообщениями с пользователями социальных сетей «Вконтакте» и Facebook, которые не так давно открыли публичный интерфейс к своим внутренним системам мессаджинга по протоколу XMPP. Как показал наш опыт с Мобильным Агентом, это наиболее частый случай использования XMPP-клиента.

Однако, несмотря на «заточенность» под социальные сети, наша реализация протокола поддерживает большинство популярных расширений (XEP'ов – XMPP Extenstion Protocol), так что Mail.Ru Агент можно использовать в качестве клиента для подключения к самым произвольным XMPP-серверам. «Из коробки» поддерживаются сервисы «Вконтакте», Facebook, Google Talk, Яндекс.Онлайн и QIP, однако при необходимости можно подключить любую учетную запись (например, на Jabber.Ru) – достаточно лишь указать в настройках JID (Jabber ID) и пароль (IP-адрес сервера будет определен автоматически по SRV-запросу к DNS).

Если говорить об особенностях реализации XMPP-клиента, то с основными проблемами мы столкнулись в области авторизации пользователей.Дело в том, что XMPP-серверы Вконтакте и Facebook авторизуют пользователей не по логинам, которые используются для авторизации на веб-сервисах и представляют собой различные адреса электронной почты, а по JID вида idXXXX@vk.com и ALIAS@chat.facebok.com, соответственно. Это логично, поскольку в протоколе XMPP домен в JID пользователя должен совпадать с доменом XMPP-сервера, к которому относится этот JID.

В случае с Вконтактом idXXXX – это некоторый внутренний идентификатор пользователя, который можно посмотреть, например, в URL своего профиля. C Facebook все оказалось несколько сложнее. По умолчанию у пользователя нет вообще никакого ALIAS'а — и хотя его можно задать в настройках своей учетной записи, в ряде случаев для подтверждения этого действия необходимо пройти SMS-авторизацию (ввести код, отправленный Facebook'ом в виде SMS-сообщения). А SMS в Россию Facebook… не доставляет (во всяком случае, так было пару месяцев назад).

Так или иначе, идея заставлять пользователя вводить в настройках Mail.Ru Агента некие «магические» идентификаторы (с которыми он никогда не сталкивается в повседневной жизни) показалась нам неудачной, так что мы сразу решили поддержать авторизацию в XMPP по тем же логину и паролю, которые используются для авторизации на вебе.

Со Вконтактом все оказалось просто – мы связались с нашими коллегами, и они предоставили нам простой API, возвращающий idXXXX по «вебовому» логину/паролю. Дальнейшее было делом техники: достаточно просто взять idXXXX и пароль, указанный пользователем в настройках Mail.Ru Агента, и авторизоваться на XMPP-сервере стандартным методом DIGEST-MD5.

Facebook же заставил нас повозиться. Кроме неудобной для пользователя авторизации по JID (методами PLAIN и DIGEST-MD5), их XMPP-сервер поддерживает также SASL-авторизацию. В теории, идея тривиальна. В клиентском приложении запускается браузер, и в нем пользователь авторизуется по своему обычному логину/паролю. После успешной авторизации сервер возвращает клиенту браузеру токен, с которым (после выполнения некоторых преобразований) выполняется уже авторизация по протоколу XMPP. К сожалению, несмотря на простоту этого механизма, в нем есть несколько тонкостей, которые документированы у Facebook весьма туманно, так что нам пришлось изучить немало девелоперских форумов и много экспериментировать. :)

Результатами этого небольшого исследования мы рады поделиться с вами (на случай, если вы когда-нибудь решите написать свой XMPP-клиент для Facebook).

Итак, для начала нам понадобится создать свое приложение в «админке» Facebook.

Помимо очевидных опций, в настройках приложения нужно отключить опцию «Disable Deprecated Auth Methods».

Для того, чтобы авторизоваться через SASL, нам необходимо получить авторизационный токен. Основная хитрость здесь заключается в правильном формировании http-запроса для OAuth-авторизации. Он должен иметь примерно такой вид:

www.facebook.com/dialog/oauth?client_id=123&response_type=token&redirect_uri=http://agent.mail.ru/&display=popup&scope=xmpp_login,offline_access

client_id здесь – это id вашего приложения,
response_type – тип данных (в данном случае – токен), который вернет сервер в случае успешной авторизации;
redirect_uri – URL, на который будет переадресован браузер после успешной авторизации, домен этого URL обязательно должен совпадать с доменом, указанным в настройках вашего приложения;
scope – запрашиваемые права доступа. Опция xmpp_login позволяет использовать полученный авторизационный токен для SASL-авторизации на XMPP-сервере, а offline_access обеспечивает этому токену «вечное» время жизни (чтобы у пользователя не было необходимости вводить логин/пароль при каждом подключении).

В случае успешной авторизации http-сервер переадресует браузер на redirect_uri, добавив к нему в качестве GET-параметра переменную access_token (собственно, авторизационный токен). Значение этой переменной представляет собой строку, разделенную на три части символом «|»:

216315195049043|19d8c4fcd929d1324ce9ed5f.1-100001685116a73|ifwc5qPhOguAhc3vaRmtCBnqv7E

Нас интересует средняя часть – ключ сессии.

Теперь необходимо установить соединение с XMPP-сервером и запросить у него авторизацию по «пропритарному» методу X-FACEBOOK-PLATFORM. В ответ на этот запрос сервер вернет challenge – строку примерно такого вида:

version=1&method=auth.xmpp_login&nonce=859F2F4CD0F6B245A22EB6382D9689DB

Далее мы формируем примерно такую строку:

api_key=321call_id=407808859method=auth.xmpp_loginnonce=859F2F4CD0F6B245A22EB6382D9689DB session_key=19d8c4fcd929d1324ce9ed5f.1-100001685116a73v=1.02b613865ef9e9f742caac8d163da3631

где api_key – это ключ API вашего приложения (не путать с ID приложения);
call_id – случайное число;
method – параметр со значением, скопированным из challenge;
nonce – идентификатор, скопированный из challenge;
session key – ключ сессии, полученный из токена;
v – некий номер версии (Facebook рекомендует использовать 1.0).

Значение после номера версии (2b613865ef9e9f742caac8d163da3631) соответствует секретному ключу вашего приложения (не путать с ключом API и ID приложения).

Обратите внимание, что параметры в этой строке следуют без каких-либо разделителей, типа амперсандов. Очередность параметров в строке важна, так как на следующем шаге мы вычисляем md5 от этой строки и формируем новую строку вида:

api_key=321&call_id=407808859&method=auth.xmpp_login&nonce=859F2F4CD0F6B245A22EB6382D9689DB&session_key=19d8c4fcd929d1324ce9ed5f.1-100001685116a73&sig=da0f8f0363a9f7e1cb479fcd88f10716&v=1.0

где все параметры аналогичны предыдущей строке, а sig – md5() от нее. Здесь параметры уже разделяем амперсандом.

Полученную строку кодируем методом base64 и авторизуемся с этими данными на XMPP-сервере:

<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">YXBpX2tleT0zMjEmY2FsbF9pZD00MDc4MDg4NTkmbWV0aG9kPWF1dGgueG1wcF9sb2dpbiZub25jZT04NTlGMkY0Q0QwRjZCMjQ1QTIyRUI2MzgyRDk2ODlEQiAmc2Vzc2lvbl9rZXk9MTlkOGM0ZmNkOTI5ZDEzMjRjZTllZDVmLjEtMTAwMDAxNjg1MTE2YTczICZzaWc9IGRhMGY4ZjAzNjNhOWY3ZTFjYjQ3OWZjZDg4ZjEwNzE2JnY9MS4w</response>

Вуаля, мы авторизовались на XMPP-сервере и можем обмениваться с ним соощениями.

Недостатком OAuth/SASL-авторизации является фактическая невозможность ее реализации на мобильных клиентах для таких платформ как J2ME и Symbian, поскольку API этих ОС не предоставляют пользовательскому приложению непосредственного доступа к браузеру (через который осуществляется получение авторизационного токена).

Приглашаем всех желающих попробовать Mail.Ru Агент 5.8 и особенно ждем впечатлений насчет работы нашего XMPP-клиента.

Илья Наумов,
руководитель проекта Mail.Ru Агент
Автор: @cameloid

Комментарии (40)

  • +6
    Поддержка Jabber это хорошо, я бы сказал, даже отлично. Но пока Mail.ru Агент не сменит свой убогий дизайн, который режет глаза, пользоваться им не совсем удобно.
    • +4
      Вам про Фому, а вы про Ерему.
    • +4
      Про интерфейс подпишусь. А заодно напомню недавний топик, в котором говорилось о том, что агент без спросу ставит с собой кучу мусора — с этим бы тоже разобраться.
    • +3
      image
  • +7
    Круто! Когда сервера самого Mail.Ru Агента будут поддерживать подключение сторонних клиентов по протоколу XMPP?
  • +4
    А когда ящики на mail.ru станут еще и jabber аккаунтами?
    В планах есть?
    • +1
      Не обязательно так. Достаточно чтобы контакты майлагента могли бы обмениваться по s2s с jabber напрямую минуя шлюзы. Мечты, мечты…
  • +6
    Мда, офигенное достижение — через 8 лет после появления мессенджер наконец-то поддерживает xmpp.

    А что не позаимствовали текст анонса у Дурова? «XMPP — это совершенно новый виток эволюции социального общения. Мы гордимся, что мировая премьера этого инновационного и захватывающего сервиса происходит именно в России» и далее по тексту.
    • +1
      Не позаимствовали, потому, что Дуров писал о внедрении протокола, а Майл.ру пишет о новостях своей программы-чатилки
      • 0
        А, ну это всё радикально меняет.

        Т.е., считаете, появление в версии мессенджера 5.8 поддержки xmpp — событие не такого масштаба, как появление её же в социальной сети?
        • 0
          Это конечно событие, но я ждал, что они сами ящики сделают jabber аккаунтами, как в свое время сделали yandex, google, facebook, livejournal и т.д.
          • 0
            Где-то здесь был тэг «сарказм», не находили?
          • 0
            насколько я знаю, у Facebook нет поддержки S2S federation, если вы об этом.
            • 0
              С ФБ я наверно поторопился :)
              Мне казалось, что после появления ящиков вида user@facebook они включили поддержку S2S federation. Не проверял.
  • –6
    Дело в том, что XMPP-серверы Вконтакте и Facebook авторизуют пользователей не по логинам, которые используются для авторизации на веб-сервисах и представляют собой различные адреса электронной почты, а по JID вида idXXXX@vk.com и ALIAS@chat.facebok.com, соответственно.
    Про фейсбук я не знаю, но для vk.com можно указать и так называемый alias, и все будет работать, изобретение всяких API для получения idXXXX это бессмысленно.

    Это логично, поскольку в протоколе XMPP домен в JID пользователя должен совпадать с доменом XMPP-сервера, к которому относится этот JID.
    Про SRV записи видимо поиск Mail.Ru не смог ничего найти.

    Дальше не читал
  • +1
    XMPP-сервер поддерживает также SASL-авторизацию. В теории, идея тривиальна. В клиентском приложении запускается браузер, и в нем пользователь авторизуется по своему обычному логину/паролю

    Не понял откуда в SASL взялся браузер, он используется давным давно во всех джаббер серверах и клиентах. Вы его с OAuth не путаете?
    • 0
      правильнее было бы сказать, что FB поддерживает авторизацию через SASL с использованием данных (ключа сессии), полученных через OAuth.
  • 0
    Мне интересно другое, зачем Mail.Ru Group поддерживать 2 клиента?
    Нет ли планов по слиянию\видоизменения ICQ и Mail агента?
    • 0
      А они уже слиялись. То есть «Мэйл-агент» сейчас поддерживает ICQ, Mail.ru и Jabber
  • 0
    >Недостатком OAuth/SASL-авторизации является фактическая невозможность ее реализации на мобильных клиентах для таких платформ как J2ME и Symbian

    На симбиане можно же через QtWebkit сделать!
    • +1
      это не очень жизнеспособное предложение. :) Qt поставляется вместе с ОС начиная с Symbian^3, которая является совсем новой системой, которая поддерживается всего несколькими телефонами. можно, конечно, включить библиотеку в состав клиентского приложения (и под Symbian 9.2 это даже должно работать), но таскать с мобильным приложением ~10-мегабайтную либу — вряд ли хорошая идея. к тому же, большая часть телефонов, находящихся пока на руках пользователей, базируется на еще старых версиях Symbian.
      • 0
        А в чём там собственно проблема? Где-то год назад мне понадобилось сделать OAuth авторизацию для работы с Dropbox под Symbian, ничего готового не нашёл конечно, начал с нуля — и в итоге всё, что касается авторизации работало отлично. Чистый Symbian C++ без Qt, работает с 9.1 и более новыми без проблем.
        • 0
          ну а как вы это делали? :) «имитировали» браузер? а если формат авторизационной странички у Dropobx поменяется — что будете делать?
          • 0
            Парсить страничку приходилось вручную, да. Но так как это было tech preview, а не готовый продукт, то случай изменения формата авторизационной странички у Dropbox во внимание не принимали, конечно. А так пришлось бы выпускать новую версию по такому случаю. :) А зачем имитировать бразуер, если есть RHTTPTransaction для работы с запросами и стандартный контрол CBrCtlInterface для отображения данных?
            • 0
              ну, в этом и проблема. :) суточная аудитория Mail.Ru Агента — это миллионы человек, у которых в любой момент может поломаться авторизация. решать эту проблему путем перераздачи клиентов для 7 различных платформ — слишком большой риск для нас.
      • 0
        Всё равно старая симба уже безнадёжный RIP.
  • 0
    Да и sasl у нас прекрасно на симбиане пашет. Пришлось правда исхитрится малость и портировать на Симбиан одну либу, но это не так уж и страшно.
  • +1
    Может быть не стоит делать такие революционные шаги? Сделайте для начала поддержку IMAP. Сейчас опять зашел в настройки, подумал, а вдруг они под шумок и IMAP прикрутили, ан нет. Все еще ждем :(
  • +4
    «Главная «фича» этой версии – поддержка протокола XMPP (Jabber), которая ранее уже появилась в мобильных клиентах для платформ Symbian и Java 2 Micro Edition.»
    А для Андроида когда будет? Один из немногих нормально выглядящих асько-клиентов, но отсутствие джаббера печалит…
  • 0
    > Поддержка протокола XMPP в Mail.Ru Агенте

    Я уж было подумал, что Mail.ru Agent перешёл полностью на протокол XMPP, ан нет…

    > «Вконтакте» и Facebook, которые не так давно открыли публичный интерфейс
    > к своим внутренним системам мессаджинга по протоколу XMPP.

    Какой же это публичный доступ? Вот когда они откроют s2s соединения со своим XMPP-сервером для любых сторонних XMPP-серверов, чтобы пользователи любых Jabber-серверов могли с ними свободно общаться, вот только тогда можно будет говорить о публичном доступе по XMPP. А так это вовсе не «публичный XMPP-доступ», а «XMPP-дырочка для своих».
    • 0
      Хорошие такие дырочки да, в них юзеров больше, чем во всех остальных jabber серверах вместе взятых!
      • 0
        Тут ключевой момент: «только для своих».
        Мне это никак не поможет общаться по XMPP с юзерами вконтакта или фейсбука пока не будет связи с другими jabber-серверами.
        Это всё равно, что Google разрешил бы своим GMail-клиентам обмениваться почтой только с пользователями, у которых почтовый ящик тоже на GMail, а с пользователями других почтовых серверов ни-ни…
  • 0
    А SMS в Россию Facebook… не доставляет (во всяком случае, так было пару месяцев назад)

    уже доставляет. в феврале не доставлял ещё, а в прошлом месяце я обнаружил, что появилась возможность позвонить и он позвонил на Tele2 моментально
  • 0
    1. то что вы описали — есть в стандартных доках и на форуме. правда несколько дней придеться убить на их изучение. описания совсем фонарь. но спс.

    2. меня интересует как dы прошли авторицация без использования браузера?

    «Недостатком OAuth/SASL-авторизации является фактическая невозможность ее реализации на мобильных клиентах для таких платформ как J2ME и Symbian»

    вы его сами реализовали?

    3. есть трабла с мультикукисами на Symbian s40. они их не понимают?

    вы писали кастомную реализацияю http?
    • 0
      опечатка в пункте №3 — там без вопрос в конце. — это утверждение

      3. есть трабла с мультикукисами на Symbian s40. они их не понимают.

      вы писали кастомную реализацияю http?
  • 0
    1. я не претендовал на открытие Америки. :)

    2, 3. на мобильных клиентах (без embedded-браузера) это практически невозможно сделать «дешево» (о чем я и написал), поэтому на этих клиента поддержки OAuth-авторизации нет.
    • 0
      сори, я че-то подумал, что это в клинетах для телефонов такую штуку сделали.

      p.s. для j2me придется делать кастомный http + надо подписывать приложение обязательно(нельзя открывать сокетное соединение на 80 порт)
      и можно пройти всю OAuth некоторым набором get и post запросов.
      мождно и без ведома клиента :) можно показывать какие-то похожие формочки с вопросами.
      ну по крайней мере пока facebook не сделает капчу.

  • 0
    ВКонтакте уже решила проблему получения списка > 500 друзей через XMPP?
    • 0
      а зачем вам весь список? можно ведь отображать только online пользователей
      • 0
        Чтобы не ждать выхода товарища в онлайн дабы написать ему сообщение, очевидно же

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное