Запрет доступа другим зарегистрированным пользователям к странице редактирования - PullRequest
4 голосов
/ 19 мая 2011

Я создаю небольшое веб-приложение, которое позволяет пользователям перечислять свои цели.Я хочу, чтобы пользователи могли редактировать только свой собственный контент.Я уже получил функцию проверки подлинности before_filter, которая проверяет, вошел ли кто-то в систему, но не проверяет, является ли пользователь создателем контента.Я попытался создать второй before_filter с именем correct_user, который имеет следующий код:

def correct_user
  @user = User.find(params[:id])
  redirect_to(user_path(current_user)) unless current_user?(@user)
end 

Кроме того, здесь вывод сервера от выполнения запроса get на редактирование моего собственного контента

Started GET "/goals/31/edit" for 127.0.0.1 at 2011-05-18 15:22:38 -0400
  Processing by GoalsController#edit as HTML
  Parameters: {"id"=>"31"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 101) LIMIT 1
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE ("users"."id" = 31) LIMIT 1
Redirected to http://localhost:3000/users/101 Completed 302 Found in 49ms
Completed 302 Found in 49ms

Для ясности, user_id, который я использую, равен 101, а goal_id, который я пытаюсь редактировать, равен 31. Может ли кто-нибудь объяснить, что именно происходит?

Кроме того, я знаю, что вы можете решить эту проблемуиспользуя драгоценный камень под названием CanCan (поскольку на этот вопрос был дан аналогичный ответ), но есть ли способ сделать это без использования драгоценного камня?Кажется, моя простая маленькая функция должна работать, но кто-то может объяснить, почему она не работает?

Ответы [ 4 ]

2 голосов
/ 19 мая 2011

С учетом следующих допущений:

  1. Модель пользователя: has_many :goals
  2. Модель цели: belongs_to :user
  3. Путь для изменения цели: /goals/:id/edit
  4. Контроллер целей, действие редактирования аутентифицировано (поэтому у вас обязательно будет current_user)

Вы должны иметь возможность доступа к цели следующим образом:

def edit
  @goal = current_user.goals.find(params[:id]) rescue redirect_to(user_path current_user)
end

Это приведет к поиску целей, принадлежащих current_user, поэтому @goal всегда будет принадлежать правильному пользователю.

2 голосов
/ 19 мая 2011

params - это хэш всех параметров, отправляемых (через поля URL или формы и т. Д.) Вашему действию. Имя параметра, если оно присутствует в URL, определяется в вашем файле маршрутов. Для ваших маршрутов контроллеров целей у вас, вероятно (предположительно) есть:

goals_path: /goals/
goal_path: /goals/:id
edit_goal_path: /goals/:id/edit

Поскольку вы получаете /goals/31/edit, params[:id] равно 31, идентификатор цели, которую вы редактируете. Первая строка в correct_user находит пользователя, идентификатор которого совпадает с идентификатором в хэше params (goal_id). Так что на самом деле вы должны делать что-то вроде этого:

def correct_user
  user = Goal.find(params[:id]).user if params[:id]
  redirect_to user_path(current_user) unless current_user?(user)
end

Это говорит о том, что найдите цель, которую кто-то хочет отредактировать (из параметров [: id]), и дайте мне пользователя, с которым она связана (вы не опубликовали свою модель цели, я предполагаю, что Цель принадлежит_ пользователю: но вы возможно, назвали это "создатель" или "владелец" вместо этого). Перенаправить, если пользователь не совпадает с текущим пользователем, вошедшим в систему. Ваш предыдущий код пытался найти пользователя с тем же идентификатором, что и редактируемая цель.

1 голос
/ 19 мая 2011

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

Вероятно, вы хотите что-то вроде

def correct_user
   @goal = Goal.find(params[:id])
   redirect_to(user_path(current_user)) unless current_user?(@goal.user)
end
0 голосов
/ 19 мая 2011

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

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

can :update, Goal, :user_id => user.id

и в вашем контроллере просто сделайте load_and_authorize_resource вверху.Никаких ручных before_filters, никаких проверок на какие-либо условия или что-то в этом роде.

и везде, где вам нужно будет что-то добавить в редактирование цели, например, в виде индекса, при перечислении ссылок вы просто помещаете что-токак link_to_if(can?(:update, goal) , "edit goal", goal_path(goal) ){}

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