Pull to refresh

Использование вебсервиса (SOAP) с аутентификацией запроса

imageПриветствую публику любителей и профессионалов разных направлений!

Заметил огромную пустующую нишу для изучения и обсуждения. Хотел бы вам предложить одну узкоспециализированную тему. Это вебсервисы и фреймворки. Если про последнее сказано много, то про первое — многим меньше. Ну а использование их вместе не составляет вообще никакого труда.


Про первое есть довольно подробные и доступные рассказы, например, вот:
Дао Вебсервиса — это раз
Вебсервисы в теории и на практике — это два
А про фреймворки можно ознакомиться и сравнить в этой статейке.
Там обсуждается удобность, безопасность и прочие качества таких фреймворков как CodeIgniter, CakePHP и Yii. Лично я остановился на последнем, впрочем работал и с CodeIgntiter'ом.

Итак, ближе к делу. В данном случае предлагаю рассмотреть пример работы Вебсервиса на основе SOAP — протокол обмена структурированными сообщениями в распределённой вычислительной среде, в фреймворке YiiFramework, впрочем от последнего здесь не так много кода. Ниже будут решены следующие задачи:
  1. Подготовка серверной стороны для приема:
  2. Подготовка клиентской стороны для проведения запросов с авторизацией и без
  3. Живой пример


Подготовка серверной стороны



Так как мы используем фреймворком, мы создаем контроллер дополняющий дефолтный встроенный, который будет полностью отвечать за работу нашего вебсервиса. В нем будет 2 метода и одна функция аутентификации. Подробнее смотрим в коментах к коду.
<?php

class ApiController extends CController {

  //данная функция определяет действие quote как действие Вебсервиса

  public function actions() {
    return array(
      'quote' => array(
        'class' => 'CWebServiceAction',
      ),
    );
  }

  //необходимо обозначить дефолтное значение false - не авторизован

  protected $authenticated = false;

  /**
   * Авторизация клиента soap
   * @param object $username
   * @param object $password
   * @return boolean result of auth
   * @soap
   */
  public function auth($username, $password) {
    // Здесь прописывается любая функция, которая выдает ПРАВДА или ЛОЖЬ при проверке логина и пароля
    // В данном случае проверяется через модель стандартные для фреймворка Yii UserIdentity и метод authenticate()
    // При положительном результате передается в переменную $authenticated значение true
    $identity = new UserIdentity($username, $password);
    if ($identity->authenticate())
      $this->authenticated = true;

    return true;
  }

 /**
   * @param mixed
   * @return mixed
   * @soap
   * */
  public function getTest($news) {
   // Элементарный пример функции по возвращению введенного текста клиенту, без проверки на аутентификацию

    return '<br />Запрос состоит из "' . $news['title'] . '". Аутентификация не требуется';
  }

  /**
   * @param mixed
   * @return mixed
   * @soap
   * */
  public function getSet($news) {

    if ($this->authenticated === true) {

      $post = new Test();

      $post->time = time();
      $post->text = $news['title'];
      $post->from = $news['from'];

      if (!$post->save()) {
        return '<br />Поле не должно превышать 50 символов. Запись не сохранена';
        Yii::app()->end();
      }
      return '<br />Запрос "' . $news['title'] . '" отправлен. Аутентификация пройдена. Запись сохранена';
    }
    else
      return '<br />Аутентификация не пройдена! Попробуйте вписать demo\demo ...';
  }


* This source code was highlighted with Source Code Highlighter.


В результате мы имеем готовый к приему запросов код. Отдельно хочу обратить ваше внимание на код в комментариях над функциями. Это не простые комментарии читателю, как я думал немного раньше. Это гораздо больше. Это теги, характеризующие работу функции с самого начала выполнения до вывода результатов. Подробнее про теги можно узнать на сайте
phpDocumentator. В нашем случае критически важен тег soap, так как именно он сообщает принадлежность функции к этому протоколу. Без него функция будет незаметна для вебсервиса. Остальные теги вполне понятны — тип данных запроса и выводимого результата.

Идем дальше.

Создание формы запроса



С формой запроса все будет очень просто. Это типичный input и submit. Экшн должен везти в то место, в котором будет размещен код подачи запроса на вебсервис с клиентской стороны у вас на хостинге. В моем случае это /post/send.
<form target="_blank" action="/post/send" method="post">
  <input type="text" value="" name="title" id="title" />
  <div class="row"><input type="submit" name="yt0" value="Послать на сайт" /></div>
</form>


* This source code was highlighted with Source Code Highlighter.

Довольно элеметарно и без заморочек. Теперь будет интереснее — смотрим код для клиента.

 $client = new SoapClient('http://URL/api/quote');

//      АУТЕНТИФИКАЦИЯ
// устанавливаем заголовок для авторизации
// магия состоит в том, что метод SoapController::auth() будет вызван именно перед действием вебсервиса.

      $wsu = 'http://schemas.xmlsoap.org/ws/2002/07/utility';
// здесь подаются данные логина и пароля в виде объекта SoapAuth
      $soapHeaders = new SoapHeader($wsu, 'auth', new SoapAuth("demo", "demo"));
      $client->__setSoapHeaders($soapHeaders);

// Аутентификация на этом заканчивается, далее можно запрашивать любые функции, требующие ее...
       echo "<h1> Ваш запрос </h1>";

//      ПРОСТОЙ ЗАПРОС
// отображаем текст в поле запроса title

      $test = $client->getTest($_POST);
      echo $test;

//       ЗАПРОС С ПРОВЕРКОЙ АВТОРИЗАЦИИ

       $test = $client->getSet($_POST);
      echo $test;


* This source code was highlighted with Source Code Highlighter.

Здесь работают сразу два запроса getTest и getSet. Первый просто возвращает значение поля, а второй возвращает и сохраняет в БД, если пользователь demo с паролем demo существует. Если нет — то в return на стороне сервера заносится соответствующая информация.

Подводя черту под этой частью статьи, следует сделать вывод, что для простого запроса клиента на сервер без сохранения данных, достаточно написать всего две строчки:

$client = new SoapClient('http://URL/api/quote');
$test = $client->getTest($_POST);


* This source code was highlighted with Source Code Highlighter.

А для сложного запроса с аутентификацией следует добавить код, для проверки пользователя и генерации соответствующих заголовков (header).

Не мудрствуя лукаво, вместо простого вывода назад введенного значения в поле можно сделать запрос на вывод значения из БД по ID записи или чему угодно. Тут уже дело вашей фантазии и элементарных навыков SQL. А вот для более серьезных изменений, которые могут сделать сторонние пользователи, необходимо делать проверку на валидность пользователей. С этими простыми примерами можно легко поднять у себя на сайте элементарный вебсервер.

Живой пример



Здесь можно потренироваться в посылке запросов.
А вот на этот УРЛ можно слать запросы со своего хостинга. http://teutonick.ru/api/quote
Результаты будут видны тут http://teutonick.ru/post/send.

Используемый материал


Официальный форум YiiFramework
Официальная документация
Сайт http://www.php.net/
Хабра.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.