在我们现在的devise_for模块中,我们至少有两个角色: admin 和 user 。我的目标是在任何给定时间,只有一个管理员,只有管理员可以创建/删除其他用户。我已经关注了这个post,因此我必须登录并拥有创建新用户的权限,因为默认情况下sign_up
页面不需要权限。但是,现在管理员和用户之间没有区别,这意味着两个角色都可以创建其他角色,这不是我想要的功能。我应该怎么做才能只有管理员才能创建其他用户,即在用户角色下访问/ users / sign_up时,会弹出错误,例如"没有足够的权限?"
让我告诉你我现在拥有的东西:
应用/策略/ user_policy.rb:
class UserPolicy
attr_reader :current_user, :model
def initialize(current_user, model)
@current_user = current_user
@user = model
end
def index?
@current_user.admin?
end
def new?
@current_user.admin?
end
def show?
@current_user.admin? or @current_user == @user
end
def create?
@current_user.admin?
end
def update?
@current_user.admin?
end
def destroy?
return false if @current_user == @user
@current_user.admin?
end
end
应用/控制器/ registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
prepend_before_action :require_no_authentication, only: [:cancel]
prepend_before_action :authenticate_scope!, only: [:new, :create, :edit, :update, :destroy]
def new
super
end
end
配置/ routes.rb中:
...
devise_for :users, :controllers => {:registrations => "registrations"}
resources :users
...
P.S。我试着看看我能为原始代码devise/registrations_controller.rb
[link]做些什么,但没有看到任何明显足以让我改变......
答案 0 :(得分:2)
这样的事情可能有所帮助:
class RegistrationsController < Devise::RegistrationsController
prepend_before_action :require_no_authentication, only: [:cancel]
prepend_before_action :authenticate_scope!, only: [:new, :create, :edit, :update, :destroy]
before_action :authorize_user!, only: [:new, :create]
def new
super
end
private
def authorize_user!
if !current_user || !current_user.admin?
redirect_to '/', notice: "Your permissions do not allow access to this page"
end
end
# Override from Devise::RegistrationsController to not sign in after sign up
def sign_up(resource_name, resource)
# Nothing to do
end
end
现在代码已经不在了,现在是时候进行一些解释了。第一部分代码添加了before_action
处理程序,该处理程序指定调用authorize_user!
方法,但仅在正在执行的操作是new
或create
时。虽然派生控制器没有定义create
方法,但它可以从基本控制器获得。 (旁注:new
方法不会在此处添加任何内容,并且可以随时删除。
authorize_user!
方法被声明为私有,因此无法从控制器外部意外调用 - 这是专门用于防止安全漏洞。
在该方法中,检查用户以确保首先登录某人,然后登录用户具有管理员权限。如果授权失败,用户将被重定向到主页(到'/'路线),并带有通知消息,告诉他们这些不值得。
从Devise sign_up
方法中调用RegistrationsController#create
方法,默认实现是立即调用sign_in
。由于最好让管理员用户登录,因此会在应用程序的RegistrationsController
中覆盖该方法,以省略不需要的sign_in
步骤。
在管理员创建用户帐户的情况下,当前用户不是管理员时,省略指向signup
页面的链接很有用。像这个片段的东西通常对我有用:
<% if current_user && current_user.admin? %><%= link_to "Sign Up", devise_signup_link %><% end %>
要使用此代码段,您需要更新link_to
标记以使用应用程序的语义(链接文本,路由,HTML属性等)。
准备好这些项目后,非管理员类型将无法访问您的signup
页面,尝试访问该页面会产生合适的错误消息。