Какова лучшая практика для исключения определенных полей/данных в УСПОКОИТЕЛЬНОМ ответе, если пользователь, запрашивающий это, не должен мочь видеть все данные?
Пример:
У человека есть Имя, Фамилия и Дата рождения.
Оба аутентифицируемых и неаутентифицируемых пользователя могут выполнить УСПОКОИТЕЛЬНЫЕ запросы к /people.xml для получения полного списка людей. Однако только аутентифицируемые пользователи должны смочь просмотреть всю информацию. У неаутентифицируемых пользователей должны только быть возвращенные поля First and Last Name (исключая данные Даты рождения).
Контроллер Человека должен проверить на аутентификацию прежде, чем создать ответ? Если пользователь аутентифицируется, они получают все, еще они только получают подмножество? Это нарушает какие-либо правила REST, куда /people.xml может отправить два отдельных результата?
По книге, REST гласит, что один ресурс должен возвращать один и тот же результат при каждом запросе.
Я бы создал пространство имен с "unauthenticated" или что-то в этом роде и сделал
/people.xml для authenticated
и
/unauthenticated/people.xml
Это может быть один и тот же контроллер, создающий разные результаты xml для каждого запроса.
Учтите, что разные представления одних и тех же данных (в зависимости от пользователя) могут иметь неожиданные последствия, если у вас есть кэш где-то посередине. Если полностью аутентифицированный пользователь сделает запрос первым, а затем «меньшим» пользователем, они могут увидеть удивительный результат: то же самое представление, что и полностью аутентифицированный пользователь раньше. Это потому, что в двух запросах нет разницы в том, что касается кеша (если вы не сообщите ему об этих проблемах). Итак, действуйте осторожно.
Я бы также предложил отдельные пространства имен, как предложил Роберт.
Вы можете использовать опцию :only
метода to_xml
для ограничения полей, возвращаемых контроллером, т.е.:
def show
@person = Person.find(params[:id])
payload = current_user.nil? ? @person.to_xml(:only =>
[:first_name, :last_name, :dob]) : @person
respond_to do |format|
format.xml { render :xml => payload }
end
end
Я использую плагин serialize_with_options
, поскольку большая часть конфигурации доступа к данным представления может быть выполнена на уровне модели.
class Person
serialize_with_options(:anonymous) do
only :first_name, :last_name, :dob
end
end
class PersonController
def show
@person = Person.find(:params[:id])
respond_to do |format|
format.xml { render :xml => current_user.nil? ? @person.to_xml(:anonymous):
@person }
end
end
end
Ссылка
Один и тот же URL может давать разные представления, в зависимости от заголовков запроса. Например, Accept
обычно используется для контроля формата ответа (например, XML или JSON). Аналогично, аутентификационные заголовки могут использоваться для управления тем, сколько данных возвращается для сущности.
No, that's fine. Это один и тот же ресурс, но с разными представлениями, основанными на информации об аутентификации. Вы также можете предоставлять разные версии в зависимости от того, что содержит заголовок Accept (кстати, его следует использовать вместо расширений файлов типа .xml), или вы можете предоставлять разные языковые версии, или вы можете отображать страницу по-разному, если у вошедшего пользователя определены определенные параметры персонализации. Все это законно. Рассмотрим веб-сайт, на котором есть поле для входа в систему. Если вы вошли в систему, страница будет другой. Это то же самое, только это не влияет на вложенную информацию как таковую. Управление кэшированием и прочее в таких случаях - это именно то, для чего предназначены Cache-Control, Vary и другие. Also see http://www.subbu.org/blog/2007/12/vary-header-for-restful-applications