我在我的rails应用程序中设置了Pundit和Devise并正常工作。但是,我不确定如何让用户在注册时决定他们的角色。
目前:
- 我有一个传递给设计新视图的 URL 参数。
- 在form_for中,我将一个名为 role 的隐藏字段设置为参数的值。
这行得通。
但我担心恶意用户可能会将此参数更改为"管理员",现在他们是管理员。
我应该如何处理?我不想在模型中施加限制,因为当我想创建管理员时,这会导致问题。 我应该覆盖设计注册控制器以在那里进行检查吗?
对于您要做的事情,您不需要覆盖 Devise 的RegistrationsController
。
如果希望管理员能够创建具有任意角色集的用户,只需使用自己的控制器即可。Devise 仍然可以轻松创建用户,因此您只需制作一个控制器来处理此问题即可。当然,不要忘记使用Pundit保护它,因此只有管理员可以使用此功能。
如果使用Confirmable
模块,此方法仍然有效。但是,由于在创建用户时不会发送确认电子邮件,因此您必须在保存模型后致电user.confirm!
以立即解锁帐户,或者使用 user.send_confirmation_instructions
手动发送确认电子邮件。
编辑:
此权威人士政策可能适用于也可能不适用于您要做的事情。您必须在此处覆盖Devise RegistrationsController
的create
操作才能使用Pundit的authorize
方法。为了干燥起见,您还应该将角色列表移动到其他地方,也许是进入模型。
class UserPolicy < Struct.new(:current_user, :target_user)
def create?
registration_roles.include?(target_user.role) if current_user.nil?
end
private
def registration_roles
%w(RED BLU Spectator)
end
end
经过相当多的谷歌搜索,我有一个答案。首先在模型中为角色粘贴一些验证 活动记录验证指南:请参阅 2.6 包含:验证器选项
在此之后,您的角色将得到验证以确保它们正确无误,您当然也可以有一个查找表。然后,您有两个选择:
- 对新记录使用条件before_save回调。然后检查新记录是否具有您的保护角色,如果是,则会引发错误。稍后捕获(在被覆盖的设计控制器中(请参阅第二个选项)。
- 覆盖设计注册控制器 请参阅此 SO 问题。并在完全覆盖的创建操作中进行一些检查。使用会话存储传递给新操作的 url 参数(也需要完全覆盖)。然后,如果创建操作失败并重定向到新角色,您仍然可以访问会话中的角色(因为除非您操作参数,否则将从 URL 中清除该角色)。
因此,无论哪种方式,您都需要覆盖注册控制器,这只是多少的情况。
我怀疑有一种方法可以只用权威人士来做到这一点。但我还没有能够让它工作。