Advego.ru - наполнение сайтов информацией

Авторизация посетителей и ограничение доступа (CodeIgniter)

14 февраля, 2008

Авторизация посетителей

С вопросами безопасности web ресурсов постоянно сталкивается каждый разработчик. И, естественно, в этой области существует масса решений. В этой статье я хочу рассказать о встроенных возможностях фрэймворка CodeIgniter, которые можно использовать для авторизации посетителей и ограничения их доступа.

Прежде всего, вкратце обрисую сложившуюся ситуацию.

Большинство web ресурсов используют для защиты пару «имя - пароль». Это не самый безопасный вариант, но зато удобный (простой) в использовании.

Более сложные методы защиты требуют от посетителя либо специальных знаний, либо покупки оборудования, либо того и другого. Например, служба WebMoney использует сертификаты для авторизации пользователей. Метод хороший, но инструкция по использованию и безопасной работе с этими сертификатами занимает несколько страниц. Обычный пользователь интернета не станет связываться с такой системой без достаточно веской причины (в случае WebMoney речь идет о его собственных деньгах).

Об аппаратной защите (вроде биометрических датчиков и т.п.) и говорить не приходиться. Эти устройства стоят денег и, зачастую, немаленьких.

Поэтому, метод авторизации с помощью имени и пароля, похоже, останется самым распространенным в обозримом будущем.

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

Естественно, этот подход далеко не самый лучший, т.к. код проверки формы будет дублироваться на каждой странице.

CodeIgniter предлагает элегантное решение этой проблемы. Идея заключается в использовании метода _remap. Если в контроллере объявлен этот метод, то обращения к любому другому методу контроллера будут переадресованы ему.

Теперь можно разместить код проверки в методе _remap и он будет выполняться для всех обращений к сайту.

Code (php)
  1. function _remap($method) {
  2.     //страницы, доступные без авторизации
  3.     $allowedPages = array(‘index’, ‘newuser’, ‘about’);
  4.     $pars = $this->uri->segment_array();
  5.     unset($pars[1]);
  6.     unset($pars[2]);
  7.     if (($method != null) &&
  8.         (($this->session->userdata(‘username’) != null) ||  in_array($method, $allowedPages))) {
  9.         call_user_func_array(array($this, $method), $pars);
  10.     }
  11.     else {
  12.         $this->index();
  13.     }
  14. }

Разберем подробнее код этого примера.

Прежде всего, я объявил массив ($allowedPages) с перечнем страниц (методов контроллера) доступных без авторизации. Перечень составлен произвольно и предполагается, что страница ‘index‘ содержит форму для ввода имени и пароля.

После этого, сохранил все сегменты адреса и удалил первые два (строки 4-6). Как вы помните, в CodeIgniter первый сегмент адреса содержит имя контроллера (оно нам не нужно), второй – имя метода (передается методу _remap в параметре $method), в остальных могут передаваться параметры (вот их нужно сохранить и передать вызываемому методу).

В строках 7, 8 проверяется можно ли вызвать указанный метод. Приведенный код вызовет метод в двух случаях:
1) если в сессии был установлен параметр ‘username‘;
2) название метода содержится в массиве $allowedPages, т.е. доступ к нему разрешен без авторизации.

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

Если условия не выполняются, будет вызван index(). Т.е. посетитель попадет на главную страницу сайта с формой ввода имени и пароля.

Как видите, все довольно просто.

Важно. Если ваш сайт содержит несколько контроллеров, то метод _remap должен быть объявлен в каждом из них.

Ограничения

Описанный метод удобно использовать, если вам достаточно одного пользователя с административными правами.

В случае, если вам нужно создавать группы пользователей и назначать им различные привилегии, то, стоит попробовать одну из библиотек авторизации, разработанных специально для CodeIgniter. Например, FreakAuth, EzAuth, UserAuth.

Кроме того, можно использовать и другие библиотеки. Например, mihailt опубликовал очень интересную статью «Использование Zend_Acl для контроля доступа в Codeigniter’e».

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

Удачи!

Понравилась статья? Подпишитесь на продолжение rss link !

Добавьте эту страницу в google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

Опубликовано в CodeIgniter, PHP

Комментарии (15)

Вы можете отслеживать обсуждение записи с помощью RSS 2.0 rss link

Вы также можете оставить комментарий, или трекбек с Вашего сайта.

  1. Tazman 14.02.2008 в 18:33 (Ответить)

    Интересный метод. Вот только с привилегиями не очень удобно. У себя я сделал так: взял за основу simplelogin. Расширил для работы с группами, добавил 2 функции: что в return показывает выполнен ли вход, и что показывает группу пользователя и все норм. В каждой функции что требует авторицации или опред. группы (у меня всего три) я приписал проверку входа и группы (всего 4 строчки copy-paste) вроде работает :)

    1. Владимир 14.02.2008 в 18:51 (Ответить)

      Идея как раз была в том, чтобы не писать код проверки во всех функциях.
      Хотя… “4 строчки copy-paste” конечно не проблема.

  2. Sam 14.02.2008 в 18:39 (Ответить)

    Некрасиво.

    1. Владимир 14.02.2008 в 18:51 (Ответить)

      Может и некрасиво, зато просто и работает 8-)

    2. Владимир 14.02.2008 в 18:53 (Ответить)

      Хочу уточнить. “Некрасиво” - это строки 5 и 6?

      1. Sam 14.02.2008 в 18:56 (Ответить)

        Некрасиво пользовать для этого _remap.

        1. Владимир 14.02.2008 в 19:07 (Ответить)

          Почему? Какие есть альтернативные варианты, кроме библиотек (кстати, некоторые из них именно _remap и используют)?

          1. Sam 14.02.2008 в 19:48 (Ответить) (Достигнут максимальный уровень вложенности комментариев)

            http://www.michaelwales.com/2007/10/erkana-codeigniter-authorization-library/

  3. ACID Jesus 15.02.2008 в 06:50 (Ответить)

    Имхо в виде хука это выглядело бы элегантней 8-)

    1. Sam 15.02.2008 в 11:27 (Ответить)

      Не уверен…

  4. mihailt 15.02.2008 в 12:21 (Ответить)

    В принципе тоже самое можно запихнуть и в конструктор или сделать хелпер в нём используя get_instance() и прописать в autoload

    для получения контроллера и его метода, лучше не обрабатывать сегменты урл, а использовать методы класса Router - fetch_class() и fetch_method()

    Erkana - вещь неплохая, правда очень сильно напоминает рапидовский Auth класс - не знаю как у них там и что но попахивает плагиатом

    Сейчас в основном использую Zend_acl и Zend_Auth чего и вам советую

    1. Sam 15.02.2008 в 14:45 (Ответить)

      Как знал, что есть это там, но недостаточно порылся. Написал своё. В общем, огромное человеческое спасибо за fetch_method().

      1. mihailt 15.02.2008 в 15:21 (Ответить)

        да не за что ;)

  5. aleXoid 02.03.2008 в 22:05 (Ответить)

    Хотел узнать. Есть ли где-нибудь описанные решения по интеграции авторизации в CodeIgniter и популярными форумами (наиболее интересны SMF и phpBB2).

    Пожалуйста, поделитесь ссылочками :)

    1. Владимир 03.03.2008 в 20:26 (Ответить)

      Честно говоря, вопрос поставил меня в тупик.

      Если я правильно понял, нужно прикрутить сайт (web службу) к форуму или наоборот. При этом если посетитель авторизировался на сайте, он должен автоматически авторизироваться на форуме.

      Мне кажется, что для решения этой задачи придется “плясать” от системы авторизации форума. Т.е. использовать общую таблицу пользователей, посмотреть какие параметры должны быть сохранены в сессии и т.п.

      Готовые решения может и существуют, но я с ними не сталкивался.

Оставить комментарий

Введите ваш комментарий

* - обязательные для заполнения поля

Quicktags: