AzoftБлогВнешняя регистрация и авторизация пользователей в системе Drupal

Внешняя регистрация и авторизация пользователей в системе Drupal

Алексей Ильчук Март 6, 2013

Сайты с регистрацией пользователей — один из популярных заказов нашему PHP-отделу. В большинстве случаев мы используем стандартные решения, но иногда приходится экспериментировать и искать нетривиальные пути. Сегодня я поделюсь с коллегами PHP-разработчиками одним из таких путей интеграции Drupal CMS со сторонним сервисом.

Детали проекта

  • Удаленный веб-сервис — хранилище учетных записей.
  • LMS (Learning Management System) — система из которой пользователи получают доступ к системе отслеживания событий. 

Задача: создать систему отслеживания событий на Drupal.

Описание логики работы системы

Пользователи получают доступ к системе отслеживания событий - трекеру. Механизм доступа выглядит не просто как получение логина и пароля, который пользователь сможет использовать для входа в систему, а вместо этого пользователь из LMS системы переходит по ссылке на трекер. Далее система отслеживания событий производит редирект пользователя на удалённый сервис с секретным кодом, где пользователь осуществляет вход в этот сервис. После авторизации удалённый сервис производит обратный редирект пользователя на трекер, а так же передает токен. При помощи него мы можем обращаться к API удалённого сервиса, что бы получить личные данные пользователя и данные аккаунта.

Следующим шагом после редиректа пользователя обратно в трекер, мы должны проверить зарегистрирован ли этот пользователь у нас в системе. Если да, то просто выполняем вход на основе его данных. Если же нет, то сначала регистрируем, а затем выполняем вход. Для этого отправляется  запрос к удалённому сервису для получения user id и прочей информации, которую в дальнейшем мы будем использовать для входа, регистрации в системе и для других запросов к API.

Инструменты и методы

Обращение к удалённому сервису производится посредством SOAP запросов. Описание API хранилища осуществляется wsdl файлом, предоставленным клиентом.

Для реализации этой задачи использовалась стандартная PHP библиотека SoapClient. На ее базе был написан класс wsdlHelper, который производит авторизацию/регистрацию пользователя и получает данные аккаунта. Краткое описание методов будет дано после кода:

 '123',
         'apipassword' => '1234'
     );
     
     private static $role = array(3 => 'broker');
     
     private static function doRequest($method, $params = array()) {
         $client = new SoapClient(self::$wsdl);
         return $client->$method(array_merge(self::$credentials, $params));
     }
     
     static function authorize($token) {
         global $user;
         
         $result = self::doRequest('firstMethod', array(
             'token' => $token
         ));
         if (!$result->valid) {
             return false;
         }
         
         // search user
         $query = db_query('SELECT uid FROM {profile_values} WHERE fid = 1 AND value = '.$result->userid);
         $uid = db_fetch_array($query);
         if ($uid) {
             $user = user_load(array('uid' =>$uid['uid']));
         } else {
             
             // register
             $user = user_save(null, array(
                 'name' => $result->username,
                 'pass' => md5(uniqid('rand', true).time()),
                 'mail' => $result->email,
                 'status' => 1,
                 'roles' => self::$role
             ));
             
             $profile = array(
                 'profile_course_stage_uid' => $result->userid,
                 'profile_firstname' => $result->firstname,
                 'profile_lastname' => $result->lastname
             );
             profile_save_profile($profile, $user, 'Personal information');
         }
         
         // authorize
         $tmp = null;
         user_authenticate_finalize($tmp);
     }
     
     static function getAccess($userId) {
         global $user;
         
         $result = self::doRequest('secondMethod', array(
             'userid' => $userId
         ));
         // This applicable only for this case.
         if ($result->success) {                              
              // fetching and parsing data.
                // put your fetching and parsing code here.
               $data = array($result->data, $result->data2);
                    $userData = unserialize($user->data);
                 $userData['course_stage'] = $data;
                 user_save($user, $userData);
         } else {
             return false;
         }
     }
 }
?>
  • doRequest – базовый метод для посылки Soap запроса.
  • Authorize – осуществляет вход и регистрацию пользователя.
  • GetAccess – позволяет получить и сохранить данные аккаунта, которые в дальнейшем будут использованы в системе.

Поскольку Drupal не позволяет создавать пользователей с произвольным ID (в нашем случае мы хотели сопоставить внешний ID пользователя с UID CMF Drupal), мы расширили профиль пользователя дополнительным полем course_stage_user_ID, где храним внешний ID пользователя, получаемый из хранилища. При авторизации мы первым делом проверяем существование пользователя с внешним ID, и если существование такого ID в системе подтверждается, мы просто получаем UID, загружаем пользователя и авторизуем его. Если же нет, то производим регистрацию.

Методы класса wsdlHelper используют стандартные функции Drupal для авторизации и регистрации пользователей.

В контексте данной задачи, нам было необходимо при каждом входе пользователя обновлять у себя данные аккаунта. Поэтому вызов метода GetAccess реализован в кастомном модуле, отвечающем за внешнюю авторизацию, в hook_user();

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

Приобретенный  опыт внешней авторизации и регистрации пользователей в системе Drupal очень полезен и пригодится для использования не только в конкретном проекте, а так же в множестве других. Мы в очередной раз убедились в гибкости Drupal в случаях,  когда нужно отойти от стандартных решений. Этот пример, как и множество других, доказывает применимость CMF Drupal в нестандартных задачах, успешное решение которых является основной целью команды разработчиков компании Азофт, не забывая при этом о полном удовлетворении требований заказчика.

Комментарии

комментарии



Content created by Alexey Ilchuk