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

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

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

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

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

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

Я был бы признателен за любые отзывы, опыт, советы и т. Д. (Любые книги по этой теме?)

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

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

Во-вторых, LDAP – это протокол облегченного доступа к каталогам, который предназначен для предоставления доступа нескольким пользователям сети к ресурсам. OpenLDAP – это обычная реализация Linux, и Active Directory Microsoft на Windows Server говорит о LDAP (с большим количеством расширений). LDAP имеет гораздо более надежную систему ACL. Общая конфигурация – это 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 хранит эту информацию в отдельной таблице базы данных, но я не знаю этого и не могу найти документацию так или иначе. Я слежу за возможной схемой для этого.

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

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

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

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

  • INSERT INTO acl VALUES (@uri, @userid, '', 'GET,POST') позволяет получить доступ к одному пользователю GET или POST
  • INSERT INTO acl VALUES (@uri, '*', 'admin,contributors', 'GET,PUT,POST,DELETE')
  • INSERT INTO acl VALUES (@uri, '*', '*', '') отказывает в доступе.

Несколько вещей, чтобы отметить:

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

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

Кажется, что вы ищете что-то, называемое списком контроля доступа aka ACL ( которое мертво согласно Zed Shaw, отличное видео).

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

Для чего-то конкретного для литиевого фреймворка (PHP) см .: Литиевый контроль доступа

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

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

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