如何防止未经授权的用户在设计中注册?

How to prevent unauthorized users from registering in Devise?

我想允许授权用户创建(和销毁)用户帐户。我已经根据 this and other questions.

中找到的提示让这部分工作了

但我也想防止未经授权的用户创建和销毁帐户。

我有自己的 registration_controller:

class RegistrationsController < Devise::RegistrationsController

  skip_before_action :require_no_authentication, only: [:new, :create, :destroy]
  skip_before_action :authenticate_scope!, only: [:destroy]
  before_action :authenticate_user!, only: [:new, :create, :destroy] # why doesn't this work? 
  
  def new
    super
  end

  def sign_up(resource_name, resource)
    # don't sign in as the new user
  end

  def destroy
    User.find(params[:id]).destroy
    redirect_to(users_path) 
  end

end

并指示我的路线在 routes.rb:

中使用它
  # Standard devise setup but allow registration when logged in
  # 
  devise_for :users, controllers: {:registrations => "registrations"}

  # Work around already-existing session controller
  # 
  devise_scope :user do
    post '/sessions/user', to: 'devise/sessions#create', via: :post
    delete '/users/:id', to: 'registrations#destroy', via: :delete
  end

  # Show and index for users
  # 
  resources :users, :only => [:show,:index]  


出于某种原因 before_action :authenticate_user! 不起作用...未经身份验证的用户仍然可以调用这些操作。我也试过 prepend_before_action :authenticate_user!,我试过按不同的顺序放置过滤器——首先在我的控制器中调用 before_action

我刚刚将我的应用程序升级到 rails 6.0.3.5 并添加了 devise 4.7.1。

为什么我需要这种不寻常的设置?这是一个业余爱好项目,只有我和我女朋友是用户。我们不希望任何人在互联网上注册。但我们有时可能想授予其他人访问权限,他们在创建帐户时将坐在我们旁边(大流行许可)。

我现在确实有一个解决方法:因为该网站会有一个混淆 URL 并且因为它是一个价值极低的目标(我无法想象有人会对我们的家庭库存感兴趣)我除非有人登录,否则不要向注册页面提供 link。这开启了知识渊博的黑客可能手动制作请求的可能性,但风险非常非常低。

但我仍然喜欢以“正确”的方式做事,所以我问这个问题。我看过 devise_invitable,但这对我的需求来说似乎太复杂了。

更新:我尝试的一个实验不是继承 Devise::RegistrationsController 和覆盖方法,而是将其复制到我的 registrations_controller 并进行编辑。然后我删除了 :require_no_authenticaton:authenticate_scope! prepend_before_actions 并将它们替换为 prepend_before_action :authenticate_user!

这应该消除对 before_actions 是否以错误顺序处理的疑问,并确保仅调用 :authenticate_user!

实验失败。显然 :authenticate_user! 在这一点上总是 returns 为真,无论用户是否真的通过了身份验证。为什么?

很明显这已经是 devise 很长一段时间的问题了。

解决方法是将 before_action 更改为:

prepend_before_action -> {authenticate_user!(force:true)}, only: [:new, :create, :destroy]

按照建议 in this issue comment