{grape} авторизация

Я пытаюсь создать restful, json api в ruby ​​- так что я использую виноград (https://github.com/intridea/grape) внутри стойки, Я не использую Rails для этого проекта, поэтому cancan, колдовство и т.д., Похоже, не лучшие варианты. Кроме того, мне бы не хотелось смешивать кучу императивной логики в декларативной DSL-рекламе.

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

Кто-нибудь реализовал что-то подобное для своего проекта в винограде? Что вы использовали?

Ответ 1

Это может быть слишком поздно, но в любом случае. Я бы рекомендовал вам использовать Pundit для авторизации, это смертельно просто. Чтобы использовать его в конечных точках API Grape, вам нужно будет включить помощников Pundit:

class API < Grape::API
  format :json

  helpers Pundit
  helpers do
    def current_user
      resource_owner
    end
  end

  mount FoosAPI
end

Теперь в ваших конечных точках API вы сможете использовать authorize foo, action?, как вы всегда делали бы в контроллерах Rails:

class FoosAPI < Grape::API
  get ':id' do
    foo = Foo.find(params[:id])
    authorize foo, :show?
    present foo, with: FooEntity
  end
end

Надеюсь, что это поможет!

Ответ 2

Я думал, что могу дать короткий комментарий по этому поводу, но поле короткое, извините, если это не будет правильным ответом, но:

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

Фундаментальный вопрос, который вы должны задать себе...

Сколько ролевой системы вы разрабатываете? Я думаю, что если это только вопрос роли public/private/admin, вероятно, вам стоит подумать, просто переместив его в разные API.

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

Реальная проблема - если вы думаете о какой-либо расширяемой/динамической системе ролей или хотите быть просто СУХОЙ. Это может быть болезненным;-). Я думаю, что реализация Rayan Bytes cancan gem должна помочь вам понять, как такая проблема может быть решена на более высоком абстрактном уровне. Для конкретной (без более высокой абстракции, такой как динамические роли) реализация должна быть хорошей, чтобы просто использовать в настоящее время хэндлеров из винограда и делегировать их обязанности модели (основное использование).

helpers do
  def current_user
    @current_user ||= User.authorize!(env)
  end

  def authenticate!
    error!('401 Unauthorized', 401) unless current_user
  end
end

так что вся история о том, как реализовать User.authorize! (env), и я считаю, что это должно быть сделано в вашей модели и строго зависит от ваших потребностей.

Ответ 3

Я не знаю, подходит ли мой ответ для вас. Недавно у меня была такая же проблема с Grape и авторизацией в проекте Rails4. И, пытаясь, я узнал об этом. В моем проекте я использую pundit для авторизации, он просит меня создать политики, и создайте правила авторизации для каждой модели, каждое правило является классом Ruby, что-то вроде этого (на странице pudit Github)

class PostPolicy < ApplicationPolicy
  def update?
    user.admin? or not record.published?
  end
end

то в API Grape я просто использую этот класс для авторизации, код вроде этого:

desc "hide a post"
post :hide do
  authenticate!
  error!( "user unauthorized for this" ) unless PostPolicy.new(current_user, @post).hide_post?
  @post.update hidden: true
  { hidden: @post.hidden }
end

помощники authenticate! и current_user - это настраиваемые помощники. Таким образом, я могу повторно использовать правила авторизации, созданные при разработке частей сайта.

Это работает для меня. Надеемся, что способ Pundit может решить ваши проблемы для авторизации Grape