Дошли руки до разборок с OpenID. Цель - прикрутить OpenID в качестве альтернативы регистрации/входу в проекте на Symfony2 PR4 (все некогда портировать на более новую версию).
Решил пойти стандартным в таких ситуациях путём:
почитал что такое OpenID;
нашел простую и работающую библиотеку (не самому же писать :3);
оформил в виде бандла к фреймворку, чтобы можно было использовать в других проектах (только разницу между pr4 и версией фреймворка нового проекта учесть, а это - мелочи).
OpenID делается в 3 основных шага:
Сгенерить URL, на который отправить пользователя для того, чтобы он подтвердил отправку своих данных;
Получить данные (после подтверждения пользователя перебрасывают обратно к нам с кучей GET-параметров информации);
Теневым запросом провайдеру OpenID проверить полученные данные (дабы юзер не наебал нас изменил данные, подменив GET запрос к нашей странице).
Первый шаг довольно просто пройти. От пользователя мы получаем его OpenID идентификатор, например, blablabla.livejournal.com. Используя этот идентификатор, с помощью Yadis discovery получаем URL провайдера, на который надо редиректнуть пользователя. Добавляем к полученному URLу параметров, где указываем информацию, которую хочется получить (мыло, имя...).
Для получения данных от провайдера достаточно реализовать скрипт, который может сграбить кучу GET-параметров, которые к нему попали.
После этого необходимо проверить полученные данные, послав теневой check_authentication запрос по ранее полученному URLу и отпарсить ответ.
В качестве готового решения был выбран простой как грабли класс LightOpenID by Mewp.
После этого - довольно легко был написан бандл (ознакомится с кодесом можно на гитхабе), который отдает сервис с методами start и finish. start реализует шаг 1, finish - получает и проверяет полученную от OpenID провайдера информацию, а также возвращает массив полученной информации (мыло, имя...).
При этом использование сервиса становится тривиальным.
/** * Example Action that sends OpenID request * and recieves returned attributes * @uses OpenIDService::start() * @uses OpenIDService::finsh() */ public function showAction() { /* * Get OpenIDService */ $oid = $this->get('openid'); /* * If it is first user request */ if (count($_GET) == 0) { /* * Redirect user to provider's authentification page */ $resp = $oid->start(); if ($resp) return $resp; /* * Or just die on error */ die('Invalid ID or another error happened'); } else { /* * When OpenID provider returned parameters via _GET * check them and show */ $attributes = $oid->finish(); if ($attributes) { var_dump($attributes); die(); } /* * Or just die on error */ die('User canceled request or another error happened (validation failed, etc...)'); } }
А вся настройка производится в конфигфайле:
# An example of ur config.yml: #openid.config: # openid: # required: # email: "contact/email" # required mail # first: "namePerson/first" # and first name from OpenID provider # # ...other required parameters # return: "openid" # name of return_to route # # if not set - returned to the same url that sent the request # default: "google.com/accounts/o8/id" # default identity is google one #