Использование OpenId брокеров Loginza.ru и Janrain.com (RPXNow.com) в Zend Framework

// Январь 13th, 2011 // Zend Framework, Веб-разработка

Когда вы пишете веб-приложение, то рано или поздно (а лучше чтобы рано) у вам приходится решать задачу авторизации пользователей на сайте. Вы лепите форму регистрации, и вроде бы всё готово. Но юзеры сейчас пошли ленивые, им надоедает заполнять очередную форму регистрации, чтобы узнать, а что собственно вы им предлагаете. Поэтому большое количество ваших посетителей просто уходят от вас, из-за того, что им лень зарегистрироваться.

Как же быть? Надо добавить OpenId авторизацию. Если вкратце, то OpenId — это технология позволяющая вам проводить авторизацию и регистрацию, используя сессию пользователя на другом сайте, который является OpenId-провайдером (например Вконтакте, Одноклассники, в которых сидит куча народу а также Gmail и огромнео количество других сайтов). Хорошо это тем, что скорее всего у пользователя есть открытая сессия в одном из сайтов, поддерживающих OpenId. Плохо то, что их много. Под каждый сайт надо писать набор функций, который будет производить авторизацию/регистрацию. К счастью, лень двигатель прогресса прогресс не стоит на месте! И появились так называемые OpenId-брокеры, сайты которые берут на себя авторизацию через сторонние сервисы, а вы работаете только с ними. Выгода налицо, один сайт вместо кучи. Однако специфика каждого конкретного OpenId-провайдера никуда не делать.

Для себя я выбрал два OpenId-брокера с которыми будет работать мое приложение.

Loginza

Для русскоговорящих пользователей (определяем по заголовкам броузера) я выбрал сервис Loginza. Замечательный OpenId провайдер, поддерживает почти все отечественные порталы, социальные сети и сайты, которые предоставляют OpenId авторизацию. Вот полный список: Яндекс, Mail.ru, Вконтакте, Рамблер.

Janrain (RPXNow)

Для западных клиентов я выбрал сервис JanRain.com. Раньше он назывался RpxNow.com поэтому и остались такие названия классов. Тоже очень неплохой сервис. Зачем его переименовали, я так и не понял. Список провайдеров: Aol, Yahoo!FacebookTwitterLinkedInGoogleMySpace, Windows Live, PayPalHyves, Verisign, MyOpenID, OpenID, Flickr, Blogger, Livejournal, WordPress and Netlog.

Термины

Теперь давайте введём термины.

OpenId-провайдер — сайт, предоставляющий услуги авторизации и регистрации через OpenID.

OpenID-брокер — сайт, предоставляющий авторизацию у регистрацию через OpenID-провайдеров.

Структура классов

Предлагаемое решение представлено в виде расширения Zend Framework.

  • Zend_OpenId_Broker_Abstract — абстрактный класс брокера.
  • Zend_OpenId_Broker_Loginza — код поддерживающий Loginza
  • Zend_OpenID_Broker_RpxNow — код поддерживающий RpxNow
  • Zend_OpenId_Provider_Abstract — Абстрактный класс провайдера
  • Zend_Openid_Provider_* — собственно сами классы для провайдеров. Содержат особенностеи тех или иных провайдеров. Все общие части выведены в Zend_OpenId_Provider_Abstract
  • ZendExtra_OpenId_Provider_Google
  • ZendExtra_OpenId_Provider_Vkontakte
  • ZendExtra_OpenId_Provider_MailRu
  • ZendExtra_OpenId_Provider_Yandex
  • ZendExtra_OpenId_Provider_Facebook
  • ZendExtra_OpenId_Provider_Twitter
  • ZendExtra_OpenId_Provider_MyOpenId
  • ZendExtra_OpenId_Provider_Aol
  • ZendExtra_OpenId_Provider_Yahoo
  • ZendExtra_OpenId_Provider_Webmoney
  • ZendExtra_OpenId_Provider_Loginza
  • ZendExtra_OpenId_Provider_Rambler

При изменении в формате выдачи данных провайдера, вам надо будет поменять всего один класс. Работа построена по принципу сервис-адапетров (в зависимости от условия какой OpenId-брокер и провайдер подключается тот или иной класс).

Авто-регистрация

При автоматической регистрации пользователи получают логин вида aol_username, где  aol — префикс openid-провайдера (в данном случай AOL), username — имя пользователя в AOL. Для пользователя с email: somename@gmail.com логин будет gmail_somename. Все префиксы вы можете сами кастомизировать, хоть сократив их до одной буквы. Пароль пользователя будет сгенерирован автоматически и выслан на его email. Для тех сервисов, которые не выдают email, он будет запрощен у пользователя. После регистрации пользователя его аватарка копируется в систему.

Также пришлось немного расширить класс ZendExtra_Auth_Result. ОН тоже есть в исходниках.

Исходники

В исходниках вам надо будет написать свои ключи, например для RpxNow в ZendExtra_OpenId_Broker_RpxNow::$_options[‘params’][‘apiKey’]

Скачать исходники ZendExtra_OpenId

UPD По просьбам трудящихся проект перенесен на GitHub: https://github.com/netandreus/exlibris

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


13 Responses to “Использование OpenId брокеров Loginza.ru и Janrain.com (RPXNow.com) в Zend Framework”

  1. Под какой лицензией исходники и не мог бы ты создать публичный репозиторий на github / bitbucket для них? Спасибо.

    P. S.
    «вам надо будет написать >>>свою<<< ключи"

  2. Вопросы:
    1. После модерации комментария мое гмайловское мыло будет видно всем?
    2. Почему ссылка на нем ведет на XML в формате http://yadis.org/ ?

    • google.com Андрей Токарчук:

      1. Если вы про этот сайт и плагин «Loginza» для WordPress то да, а если разрабатываемое вами приложение то как закодите :-)
      2. Опять же потому, что так закодили. По идее ссылка должна идти на ваш профиль.

  3. Пардон, удалите пожалуйста коммент…

  4. twitter.com GasheK:

    Спасибо, целый день искал как скрестить loginzу и Zend FrameWork

  5. Просто Гость:

    А можно посмотреть пример в контроллере?
    спс)

    • google.com Андрей Токарчук:

      Мы используем сервисный слой, поэтому сам код будет в сервисе. Инициализация сервис-адаптера и его параметров — в действии контроллера. $brokerName — пережается в url к брокеру (Loginza/RpxNow) а потом возвращается обратно (происходит переход ан url, в котором указано название брокера).

      Вот пример:

          public function authenticate($adapterParams)
          {
             if($adapterParams['token'] == NULL OR $adapterParams['broker'] == NULL) {
                  //throw new Exception('Empty token recieved from OpenIdProvider or broker name. User canceled auth operation.', 500);
                  $authStatus = new ZendExtra_Auth_Result(ZendExtra_Auth_Result::FAILURE_CANCELLED, NULL, array());
                  return $authStatus;
             }
      
             // Инициализация
             $brokerClassname = $this->_getCurrentBrokerClassname($adapterParams['broker']);
             $this->_broker = new $brokerClassname;
      
              if(!key_exists('token', $adapterParams) OR !$adapterParams['token'])
                  throw new Exception('OpenId token not defined', 500);
      
              // Аутентификация в брокере
              $authStatus = $this->_broker->authenticate($adapterParams);
              $this->_session->openidData = $this->_broker->getUserData();
      ...
      }
          /**
           * Возвращает имя класса OpenId-брокера по заголовку
           */
          protected function _getCurrentBrokerClassname($brokerName)
          {
              switch ($brokerName) {
                  case "loginza":
                      $brokerClass = 'ZendExtra_OpenId_Broker_Loginza';
                  break;
      
                  case 'rpxnow':
                      $brokerClass = 'ZendExtra_OpenId_Broker_Rpxnow';
                  break;
      
                  default:
                      throw new Exception('Unknown broker type or unsupported openid broker ('.$httpOrigin.')', 500);
                  break;
              }
      
              return $brokerClass;
          }
      
  6. anatoli:

    А можете выложить рабочий пример и его код ? =)

Комментировать