Yii и авторизация по OpenID.

Yiiframework 25 марта 2010 г., 17:00

При разработке одного из проектов, возникла задача дать возможность пользователю авторизоваться по OpenID. Так как проект писался на Yii, то я начал поиски компонента для этого фреймворка, который помог бы мне с этой задачей. Был задан вопрос на форуме ответа так и не последовало =(.
Было принято решение написать такой компонент (или что-то подобное) самому. Изначально я не планировал разбираться во всех тонкостях протокола OpenID, а потому решил просто написать обертку (врапер) для одной из существующих библиотек. В качестве такой библиотеки была выбрана вот эта openidenabled.com/php-openid/.
Возможно как раз из-за нехватки знаний о каких-то специфических тонкостях протокола и его реализации в этой библиотеке, привело к тому, что, полученный врапер работал (и сейчас работает) не совсем корректно. О том, что именно не так расскажу чуть позже.

После некоторого времени разработки я получил вот такой вот классик-оболочку, который очень легко и удобно (на мой взгляд) использовать.
Установка.
1. Скачиваем или делаем чекаут из SVN.
2. Распаковываем архив.
3. Каталог OpenId, содержащий библиотеку openidenabled.com/php-openid/ переносим в application.extensions
4. Сам класс-оболочку (YOpenIdAuth.php) переносим в любой каталог доступный Yii.

Установка завершена!

Как всем этим пользоваться.
Приведу пример своего котроллера (Код методов — не полный, только то, что касается OpenID):



class UserController extends YFrontMainController
{   
    public $auth;
    
    public function init()
    {        
        try{            
           $this->auth = new  YOpenIdAuth(Yii::app()->params['returnTo'],Yii::app()->params['trustRoot']);    
        }
        catch(Exception $e)
        {
            Yii::app()->user->setFlash('error','Ошибка авторизации!
Попробуйте позже!');
            $this->redirect(Yii::app()->homeUrl);
        }
    }



    public function actionLogin()
    {        
        $this->setTitle("Авторизация");       
        if(count($_GET) && isset($_GET['openid_identifier']))
        { 
          $auth = $this->auth;          
          try
          {
            $auth->authenticate($_GET['openid_identifier']);            
          }
          catch(Exception $e)
          {
            Yii::app()->user->setFlash('error',$e->getMessage()); 
          }          
        }        
        $this->render('login');
     }



     public function actionOpenIdFinal()
     {
        if(!count($_GET))
        {
            throw new YPageNotFoundException();
        }
        
        try
        {        
            $auth = $this->auth;            
            $openIdUser = $auth->finalAuth();            
        }
        catch(Exception $e)
        {
              Yii::app()->user->setFlash('error','При авторизации произошла ошибка!');
              Yii::log("Error OpenId Auth...".$e->getMessage(),CLogger::LEVEL_ERROR);
              $this->redirect(Yii::app()->homeUrl);
        }
     }
    
}  




Что же тут происходит:

1. В методе init() создается экземпляр моего класса-оболочки, в качестве параметров конструктор получает две строки:
— ссылка на которую произойдет редирект после авторизации на сайте OpeId — провайдера
— ссылка которая будет отображена на сайте OpenId — провайдера

 $this->auth = new YOpenIdAuth(Yii::app()->params['returnTo'],Yii::app()->params['trustRoot']);    

Эти параметры для удобства я вынес в конфигурационный файл приложения.
2. Экшн actionLogin() — он должен просто принять URL-адресс OpenID-провайдера и передать его в мтод authenticate() моего класса.

$auth->authenticate($_GET['openid_identifier']);            

3. Экшн actionOpenIdFinal() на этот экшн будет произведен редирект с сайта OpenID-провайдера. Т.е. именно в этом экшене необходимо обработать ответ от OpenID-провайдера и получить информацию о пользователе.

 $openIdUser = $auth->finalAuth();

В результате вызова этого метода в переменной $openIdUser получим массив информации о пользователе (если авторизация прошла корректно), содержащий следующие параметры:
— openIdLink — url OpenId-провайдера,
— nickname — ник пользователя,
— email — email пользователя,
— fullname — полное имя пользователя

Что же хочется исправить и для чего я опубликовал эту заметку.

1. Сейчас это просто класс и он имеет мало общего с компонентами Yii — хочется, что бы он соответствовал всем параметрам CComponent.
2. Возможно мой врапер использует не все возможности протокола OpenID и не все возможности используемой библиотеки.
3. Хочется провести полный рефакторинг кода.
4. Расширить его функциональность и конфигурируемость.
5. Заставить его работать с openid.mail.ru/ и стабильно работать с openid.yandex.ru/ (сейчас авторизация проходит не всегда)

Этот классик был написан буквально за пару часов, поэтому качество когда не совсем такое, какое хочется получить в финале.

Хочу призвать все русскоязычное (и не только) Yii-сообщество к написанию такого необходимого компонента.

В итоге хочется получить хороший и стабильный компонент для авторизации по OpenID в Yii.

Юпи! — CMS на Yii – http://yupe.ru

Исходный код – https://github.com/yupe/yupe

Присоединяйтесь!

Теги: openid yii xoma 5


Комментарии 10

bootk
bootk
Как дела обстоят сейчас? Появился экстэншн copenid что можете сказать про него?
xoma
xoma
На данный момент вторая версия этого экстеншена работает вот тут http://sprosiotvechu.ru/openid/index пока не очень стабильно правда. Довести до ума и выложить — все не хватает времени, но обязательно сделаю. Если есть время и желание помочь — буду рад =)
bootk
bootk
А что не стабильно? Просто передо мной сейчас стоит задача реализовать openid, вот выбираю с какого конца бы подойти, что б быстрее и безболезненнее) Может вместе допилим до конца.
xoma
xoma
могу предложить протестировать работу библиотеки по выше указанной ссылке, если она все Ваши потребности удовлетворит (пройдет авторизация на всех необходимых сайтах) — я ее выложу в паблик.
xoma
xoma
p.s. я имел ввиду свое расширение, а не copenid
tyler
tyler
вот мой патч для google apps for domain openid, может пригодится при совершенствовании компонента pastebin.com/xJWBkeaL
xoma
xoma
О! спасибо большое! «внедрю» ваш код во вторую версию библиотеки!
tyler
tyler
рад помочь, русские каменты удалил ибо для заказчика нерусского делалось. вы мне тоже помогли этой статьей :)
tyler
tyler
спасибо, вот :)
xoma
xoma
пожалуйста =)
Пожалуйста, авторизуйтесь или зарегистрируйтесь для комментирования!