Только разрешить пользователю администратора создавать новые пользователи в Rails с помощью Devise (без внешних модулей)

В настоящее время в моей базе данных пользователей имеется столбец с именем "admin" с логическим значением, а по умолчанию установлено значение "false". У меня есть один пользователь admin, загруженный в базу данных.

Как написать мое приложение, чтобы пользователи, , могли создавать новых пользователей, но пользователи, которые не, не могут? (Кроме того, администратор должен создавать только)

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

Я бы с большей вероятностью выделил решение, которое разрабатывается только. (Тот, который является просто стандартным решением MVC/Rails a plus) Однако, если есть лучший способ сделать это, который не включает CanCan я может принять это тоже.

Примечание:

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

Ответ 1

Чтобы реализовать авторизацию, используйте метод на контроллере

Именно так, как было предложено @diego.greyrobot

class UsersController < ApplicationController
  before_filter :authorize_admin, only: :create

  def create
    # admins only
  end

  private

  # This should probably be abstracted to ApplicationController
  # as shown by diego.greyrobot
  def authorize_admin
    return unless !current_user.admin?
    redirect_to root_path, alert: 'Admins only!'
  end
end

Чтобы обойти проблему "уже зарегистрированный" в Devise, определите новый маршрут для создания пользователей.

Мы просто определим новый маршрут для обработки создания пользователей, а затем укажите форму в этом месте. Таким образом, представление формы не проходит через контроллер разработки, поэтому вы можете свободно использовать его в любом месте в обычном режиме Rails.

# routes.rb
Rails.application.routes.draw do

  devise_for :users
  resources :users, except: :create

  # Name it however you want
  post 'create_user' => 'users#create', as: :create_user      

end

# users/new.html.erb
# notice the url argument
<%= form_for User.new, url: create_user_path do |f| %>
  # The form content
<% end %>

Ответ 2

Проблема концептуальна. Devise - это только библиотека аутентификации, а не библиотека авторизации. Вы должны реализовать это отдельно или использовать CanCan. Не пожалей, однако, в вашем случае легко реализовать это, поскольку у вас есть только одна роль.

Защитите своего пользователя от создания/обновления/уничтожения с помощью фильтра before:

class UsersController < ApplicationController
  before_filter :authorize_admin, except [:index, :show]

  def create
    # user create code (can't get here if not admin)
  end
end

class ApplicationController < ActionController::Base
  def authorize_admin
    redirect_to root_path, alert: 'Access Denied' unless current_user.admin?
  end
end

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

Ответ 3

Это кажется упрощенным подходом. Это просто требует подклассификации устройства разработки. См. Документы о том, как это сделать.

# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  before_action :authenticate_user!, :redirect_unless_admin,  only: [:new, :create]
  skip_before_action :require_no_authentication

  private
  def redirect_unless_admin
    unless current_user.try(:admin?)
      flash[:error] = "Only admins can do that"
      redirect_to root_path
    end
  end

  def sign_up(resource_name, resource)
    true
  end
end


# config/routes.rb
Rails.application.routes.draw do
  devise_for :users, :controllers => { :registrations => 'registrations'}
end

Explaination:

  • Подкласс контроллера регистрации и создание маршрута для него.
  • before_action гарантирует, что пользователь войдет в систему и перенаправляет их, если они не являются администратором, если они пытаются зарегистрироваться.
  • Идентифицированная проблема вызвана методом Devise require_no_authentication, и ее пропускание устраняет проблему.
  • Далее следует, что вновь созданный пользователь автоматически подписывается. Вспомогательный метод sign_up, который делает это, переопределяется, чтобы предотвратить автоматическую регистрацию.
  • Наконец, флаговое сообщение Welcome! You have signed up successfully. может быть изменено путем редактирования файла config/locales/devise.en.yml, если это необходимо.