Реализация авторизации пользователей на PHP и Javascript


Предполагая, что у меня есть действительный сеанс и аутентифицированный пользователь, каковы некоторые способы реализации авторизации пользователя в приложении с бэкэндом PHP/MySQL и мощным интерфейсом JavaScript?

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

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

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

Я пошел в местный книжный магазин и провел день, просматривая все, что у них было на PHP, MySQL и JavaScript. Удивительно, но большинство из книг практически ничего не было об авторизации пользователя. Это пугает меня до чертиков! Это должен решить любой, кто создает большое веб-приложение, использующее AJAX, я просто не могу найти что-то, что помогло бы мне начать.

Я был бы признателен за любые отзывы, опыт, советы и т.д. (Есть какие-нибудь книги на эту тему?)

Author: Jonathan, 2012-01-17

3 answers

Безопасность PHP, похоже, застряла в темных веках, когда один пароль дает токен для одного пользователя для класса определенных страниц. Похоже, вы хотите сделать свое приложение более детальным, возможно, даже разрешить доступ к определенным частям ресурсов в зависимости от этого маркера входа. Ваша мысль о списках контроля доступа абсолютно верна, и да, вы открыли темную тайну: никто на самом деле не опубликовал, как разработать или написать механизм ACL. Тем не менее, это было готово.

Во-первых, знакомы ли вы с правами доступа к файлам unix? Это -rwxr-xr-x вещи, которые вы видите в ls -l в командной строке. Unix выбрала очень упрощенный подход к спискам управления доступом. У каждого вошедшего в систему пользователя есть идентификатор пользователя (UID) и один или несколько идентификаторов групп (GID) (whoami, groups). Права доступа к файлам Unix позволяют выполнять три операции, Read, Write, и Execute, который может быть включен или выключен. С 2^^9 состояниями эти разрешения легко помещаются в целое число, и Unix может затем присоединить это целое число к файл непосредственно в файловой системе. Когда пользователь пытается получить доступ к файлу, разрешения сравниваются от строгих до разрешительных, сопоставляя наиболее разрешенные привилегии. Таким образом, пользователи получают первый набор разрешений, группы получают второй, а любой пользователь получает третий. Таким образом, исполняемый файл обычно равен 755: только владелец может его изменить, но любой может прочитать и использовать его.

Во-вторых, LDAP - это Облегченный протокол доступа к каталогам, система, предназначенная для предоставления нескольким пользователям сети доступа к ресурсы. OpenLDAP - это распространенная реализация Linux, и Microsoft Active Directory на Windows Server использует LDAP (с множеством расширений). LDAP имеет гораздо более надежную систему списков управления доступом. Общая конфигурация access to [resources] by [who] [type of access granted] [control] или access to dn="uid=matt,ou=Users,dc=example,dc=com" by * none предназначена для ограничения всего доступа к пользовательской информации Мэтта. Для более полного обсуждения я бы настоятельно рекомендовал Освоить LDAP, в частности главу 4 о безопасности. (Вот где я немного извлекаю из своих прямых знаний.) У меня сложилось впечатление, что LDAP хранит эту информацию в отдельной таблице базы данных, но я этого не знаю и так или иначе не могу найти документацию. Я внимательно слежу за возможной схемой для этого.

Короткая остановка для подведения итогов: Списки управления доступом содержат концепцию пользовательского токена с возможными группами выше уровня пользователя, набор объектов, которые необходимо каким-либо образом защитить, и несколько последовательных возможных операций с этими частями - 3 измерения информации. Unix хранит два из этих измерений с тем, что должно быть защищен напрямую. OpenLDAP хранит эти три измерения отдельно, каким-то образом, мы не совсем знаем, но я подозреваю, что это связанная древовидная структура.

Учитывая это, давайте посмотрим, как мы могли бы разработать систему ACL для веб-приложения RESTful. Для предположений мы разобьем ваше приложение на отдельные адресуемые единицы - каждая вещь, которую необходимо защитить, будет доступна через URI (http://example.com/users, http://example.com/page_pieces/ticker). Наши пользователи будут иметь простой токен UID/GIDS - пользователь может быть частью нескольких группы. Наконец, наши доступные операции будут основаны на HTTP-запросах - GET, POST, PUT, DELETE и т.д. Теперь нам нужна система, которая эффективно обрабатывает трехмерный массив данных. Наша схема должна быть довольно очевидной: (uri, userid, groupid, operations). Мы намеренно денормализуем столбец operations в строковый список GET,POST,..., поэтому нам нужна только одна таблица. Первичного ключа нет, так как мы никогда не будем искать его по идентификатору.

Запросы будут выполняться в два этапа: SELECT * FROM acl WHERE uri=@uri, userid=@userid, которые вернут 0 или 1 строку. Если это возвращает 1 строку, мы закончили и можем проверить permisssion, чтобы увидеть, есть ли операция в списке (используйте *, чтобы указать все завивки). Если мы получили 0 строк, запустите второй запрос SELECT * FROM acl WHERE uri=@uri, userid='*', groupid in (@groupid), который снова вернет 0 или несколько строк. Если он вернет что-то, просмотрите и посмотрите на завивки. Если он возвращает 0, выполните последний запрос SELECT * FROM acl WHERE uri=@uri, userid='*', groupid='*', который в конечном итоге вернет 0 или 1 строку. Если он возвращает 1, посмотрите на завивку. Если он возвращает 0, выполните действие по умолчанию.

Мы можем установить разрешения несколькими способами:

  • INSERT INTO acl VALUES (@uri, @userid, '', 'GET,POST') позволяет один пользователь ПОЛУЧАЕТ или ПУБЛИКУЕТ доступ
  • INSERT INTO acl VALUES (@uri, '*', 'admin,contributors', 'GET,PUT,POST,DELETE')
  • INSERT INTO acl VALUES (@uri, '*', '*', '') запрещает любой доступ.

Пара вещей, которые следует отметить:

  1. Все URI должны быть выражены точно; это решение не позволяет установить разрешения по умолчанию на более высоком уровне и заставить их просачиваться вниз (оставлено в качестве упражнения для спрашивающего).

  2. Уникальность пар uri/uid/gid должна произойти в какой-то момент. Приложение может справиться с этим, или в MySQL вы можете сделать ALTER TABLE acl ADD UNIQUE INDEX (uri, userid, groupid) (посмотрите документацию для аналогичные ограничения в других СУБД).

 7
Author: David Souther, 2012-01-17 16:18:57

Похоже, что вы ищете что-то под названием Список контроля доступа, он же ACL (, который мертв согласно Зеду Шоу, отличное видео).

Довольно сложно дать вам решение, не зная, какой у вас бэкэнд, но вы можете проверить, как это делают другие.

Что-то конкретное для платформы lithium (PHP) см. в разделе: Управление доступом к литию

 4
Author: greut, 2017-05-23 10:29:27

Вот что я понимаю:

Вам нужно создать список контроля доступа для ваших пользователей? а ты? [поправьте меня, если я ошибаюсь]

Я предлагаю вам создать таблицу БД, в которой вы можете хранить идентификатор пользователя (или имя пользователя) и какой у него доступ к вашему веб-приложению. Затем вы можете проверить таблицу, чтобы узнать, доступен ли запрошенный URL/ресурс для этого пользователя. Это все.

 1
Author: Fabio Buda, 2012-01-17 15:12:55