Подтвердить что ты не робот

Лучшая маршрутизация маршрута RESTful при обращении к current_user с маршрута?

У меня типичные маршруты RESTful для пользователя:

/user/:id
/user/:id/edit
/user/:id/newsfeed

Однако маршрут /user/:id/edit может быть доступен только тогда, когда id равен идентификатору current_user. Поскольку я хочу, чтобы current_user имел доступ к редактированию своего профиля. Я не хочу, чтобы другие пользователи могли редактировать профили, которые не принадлежат им.

Как правило, лучше всего справиться с этой ситуацией?

Должен ли я оставить маршрут как есть, и через ошибку, если current_user.id != param[:id], заставляя клиентского интерфейса, вызывающего api, отслеживать зарегистрированный идентификатор пользователя?

Должен ли я сделать специальный маршрут /user/self/edit и в контроллере проверить, есть ли param[:id] == 'self'?

4b9b3361

Ответ 1

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

/my-profile/edit
/my-profile/newsfeed

Это не тот RESTful, но вам не нужно ставить лишние проверки, чтобы ваш код был чистым.

Если вам все еще нужно (или хотите иметь) строгие маршруты RESTful, я бы использовал файл before_filter и проверить, равен ли id = current_user.id. Если нет, верните 401 или 403.

Ответ 2

Я хочу, чтобы current_user имел доступ к редактированию своего профиля. я не хотите, чтобы другие пользователи могли редактировать профили, не принадлежащие их.

Я предлагаю использовать некоторые графы авторизации, например pundit p >

Пример кода:

class UserPolicy
  attr_reader :current_user, :model

  def initialize(current_user, model)
    @current_user = current_user
    @user = model
  end

  def edit?
    @current_user == @user
  end
end

Также с аутентификационным камнем, например Разработать, только current_user (пользователи, которые вошли в систему) могут просматривать и редактировать свои профили только

Ответ 3

Я бы сказал, что вы делаете это правильно, просто сохраняйте свой текущий маршрут, как сейчас. И что вы должны сделать, так это добавить ограничение в свой контроллер. Я бы предположил, что вы используете Rails и работаете с users_controller.

class UsersController < ApplicationController::Base
  def edit
    if current_user.id == params[:id]
      # do your work
    else
      render :404
    end
  end
end

Или вы можете очистить свой контроллер, переместив ограничение на обратный вызов:

class UsersController < ApplicationController::Base
  before_filter :restrict_user, only: [:edit]

  def edit
    # do your work
  end

  private
  def restrict_user
    render :404 unless current_user.id == params[:id]
  end
end

Ответ 4

Вы можете добавить gem "cancancan" и после инициализации....

    class Ability
        include CanCan::Ability

        def initialize(user)

            can :update, User do |user|
                 user.id == params[:id]
            end
        end
    end

Затем добавьте этот authorize! :edit, @user к вашему действию обновления

Ответ 5

Вам нужно будет добавить код авторизации во всех методах user_controller в качестве другого комментария. Обычно то, что я делаю в приложениях, где пользователь должен только редактировать свой собственный профиль, я добавляю маршрут/профиль для пользователя, чтобы отредактировать свой собственный профиль, а затем на маршрутах main/users/: id/*. Я добавляю логику, чтобы предотвратить -admin пользователей от доступа к этим маршрутам.

Ответ 6

Пользователь может просматривать его профиль /users/1 или редактировать его профиль /users/1/edit. С точки зрения пользователей эти URL-адреса абсолютно прекрасны.

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

Вам не нужно беспокоиться о удобстве "хакеров". Я всегда использую current_user в действии edit, поэтому никто не может редактировать неправильный профиль независимо от его профиля.

def edit
  @user = current_user
end

Кроме того, я должен упомянуть, что вы должны также покрыть действие update с такими проверками. С помощью edit вы можете получать данные (и, возможно, только широко открытые открытые данные, если вы не добавили в шаблон edit платежную информацию или текстовые пароли). Но с update вы можете реально изменить данные, которые могут быть более разрушительными.

Ответ 7

Поскольку кажется, что единственный доступный пользовательский ресурс должен быть аутентифицированным пользователем, я думаю, что лучший способ решить это -

GET /user
PUT /user
GET /user/newsfeed

Если вам нравится расширять использование api в будущем, чтобы один пользователь мог получить доступ к другим ресурсам пользователя, вам нужно решение, которое включает идентификаторы пользователя. Здесь имеет смысл вводить маршруты для "я" тоже. Но тогда вам также нужно выполнить проверку доступа на стороне сервера.

GET /user/id/:id
PUT /user/id/:id
GET /user/id/:id/newsfeed

GET /user/self
PUT /user/self
GET /user/self/newsfeed

Но я думаю, вы должны держать его как можно проще

Для дальнейших исследований я бы предложил такие книги, как http://apigee.com/about/resources/ebooks/web-api-design, которые дают хорошее представление о дизайне API

Ответ 8

Поскольку вы только хотите предоставить конечные точки RESTful только для текущего пользователя, прошедшего проверку подлинности, который доступен в ваших контроллерах как current_user, я говорю, что вам не нужен параметр идентификатора id. Я предлагаю использовать следующие маршруты:

GET /user => users#show
PUT/PATCH /user => users#update
GET /user/edit => users#edit

Ответ 9

Вы должны сохранить url как есть. Аутентификация и авторизация являются отдельными проблемами. "current_user" относится к пользователю, который прошел аутентификацию для доступа к apis. Идентификатор в URL-адресе идентифицирует ресурс, на котором работает "current_user", так что у него есть доступ к этому ресурсу или нет, это проблема авторизации. Поэтому вы должны добавить current_user.id != param[:id] (как вы упомянули) в свои разрешения api и выдать код статуса 403 в ответ.

Ответ 10

Вы должны использовать этот маршрут:

PUT /user/me

Обратите внимание, что нет необходимости в "редактировании": вместо этого вы должны использовать метод PUT.

Кроме того, вы должны явно указать маршрут, который я написал выше, вместо проверки, если id == 'self'.