Использование скрытых полей для размещения данных внешнего ключа для дочерней записи? - PullRequest
0 голосов
/ 15 октября 2010

Позволяет ли использование скрытых полей в форме кого-либо подделывать данные в скрытых полях, которые отправляются обратно?

Например, в моем приложении на Rails у меня есть структура parent-child, где я вызываю new_project_task (@project), который выполняет действие создания контроллера, и на странице я не хочу показывать поле для чужойключ (project_id), потому что я не хочу, чтобы пользователь видел или редактировал его.Однако, если я оставляю поле вне формы, когда дочерняя запись сохраняется, идентификатор_проекта не сохраняется в записи.Итак, я использую скрытое поле для хранения значения внешнего ключа, и оно работает правильно во время обратной передачи, чтобы передать это значение в запись дочерней задачи.

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

Итак, есть ли лучший способ для Rails справиться с этим?

Ответы [ 3 ]

3 голосов
/ 15 октября 2010

Ответ на ваш вопрос сводится к тому, что вы беспокоитесь.Вы хотите предотвратить ошибки пользователя или предотвратить злонамеренное использование?

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

Если вы пытаетесь предотвратить злонамеренное использование, это становится более проблематичным - но опять же, это зависит от того, что вы пытаетесь предотвратить.

Если вы пытаетесь запретить пользователям добавлять задачи в проекты, к которым у них тоже нет доступа, используйте какую-то систему разрешений, чтобы запретить пользователю доступ к определенным проектам.Самый простой способ для этого - просто установить отношения между пользователями и проектами, а затем использовать current_user.projects.find(params[:project_id]).tasks.create (или аналогичный) в вашем контроллере.

Теперь, если вы абсолютно, положительно, не хотите, чтобы пользователидобавить задачи в любой другой проект - точка - вы можете рассмотреть возможность предварительного создания задачи.По сути, вы должны создать задачу в своем действии new и перенаправить пользователя на действие редактирования.Примерно так:

def new
  @project = Project.find(1) # Or however you want to fetch the project
  @task = @project.tasks.create
  redirect_to edit_project_task(@project, @task) # May vary depending on your routes
end

При таком подходе вы захотите полностью удалить действие create.

1 голос
/ 15 октября 2010

В моей практике я бы предпочел встраивать идентификатор_проекта в URL (используя ресурсоемкие маршруты)

, т.е./project/:project_id/task

На самом деле, я не буду доверять большинству вещей, возвращающихся из формы.(Представьте, что кто-то создал свой собственный прокси-сервер и, таким образом, может изменить данные формы на что-нибудь еще!)

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

Конечно, вы можетевстроить его в скрытое поле, оно действительно (хотя это не мое личное предпочтение).Но это не имеет значения, если пользователь «волшебным образом» изменил скрытое поле на другое значение.Вы просто вставляете или отказываетесь, вот и все: D

0 голосов
/ 15 октября 2010

Когда вы используете parent / child (project / task), вы должны использовать restful url для их интерфейса crud.Когда вы создаете задачу для проекта, вы публикуете URL-адрес создания задачи для этого проекта.Маршруты должны выглядеть примерно так:

resources :projects do
  resources :tasks
end

Затем, когда вы определите new_project_task_path(@project), вы получите URL-адрес типа /projects/1/tasks/new, где 1 будет идентификатором проекта.Затем в действиях контроллера вы должны сделать следующее:

def create
  Project.find(params[:project_id]).tasks.create(params[:task])
end

И все будет сделано за вас.Если вы пытаетесь добавить задачу в проект, принадлежащий конкретному пользователю, сделайте следующее:

def create
  current_user.projects.find(params[:project_id]).tasks.create(params[:task])
end

Чтобы упростить код в действиях, вы можете определить before_filter, который найдет проект для вас и поместит егов @project переменную экземпляра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...