我想在我的应用程序中有一个 /admin 部分,并在此 /admin 部分中有路由,例如:
www.example.com/admin/(只有某些用户有权访问此部分)
然后在该部分添加控制器,例如:
/admin/users/{add, new, etc}
对于这样的事情我有什么选择? (使用导轨3)
我更喜欢做与托德的回答类似但略有不同的事情。与其将 before_filter 添加到与管理内容相关的每个控制器,我更喜欢创建一个 AdminController,所有与管理操作相关的控制器都可以从中继承:
# config/routes.rb
namespace :admin do
resources :users
end
# app/controllers/admin_controller.rb
class AdminController < ApplicationController
before_filter :authorized?
private
def authorized?
unless current_user.has_role? :admin
flash[:error] = "You are not authorized to view that page."
redirect_to root_path
end
end
end
# app/controllers/admin/users_controller.rb
class Admin::UsersController < AdminController
...
end
在你的routes.rb中做类似的事情:
namespace :admin do
resources :users
end
请参阅 http://guides.rubyonrails.org/routing.html 了解更多详情。
然后在每个管理控制器中,您将需要一个 before_filter:
before_filter :authorized?
def authorized?
#check if authorized here.
end
正如托德提到的,您想要添加命名空间路由:
namespace :admin do
resources :users
end
您还需要将控制器、视图等放入每个部分的子文件夹中,称为“admin/”。 如果您从头开始生成它,这很容易:
rails g controller admin/users
这可能看起来相当复杂,但我有一篇文章介绍了所有这些内容,其中包含一个示例 Rails 3 应用程序,您可以下载来使用它:
然后在每个管理控制器中,您需要一个 before_filter:
before_filter :authorized? def authorized? #check if authorized here. end
我认为如果他把这段代码放到一个继承自ApplicationController的主AdminController中会更好,那么每个管理控制器都会继承这个AdminController。
关于Rails3,这里是一篇关于路线的好文章
显然托德所说的是正确的。但是,如果您喜欢通过隐藏来提高安全性,您还可以保留
new_admin_user
url 帮助程序和 Admin::
命名空间控制器,但提供一个不太广泛使用的公共 url 路径,其中包含以下内容:
scope :module => "admin", :as => 'admin', :path => 'xyz' do
resources :user
end
A
rake route
使用该设置将显示沿这些线的路线:
new_admin_user GET /xyz/users/new(.:format) {:controller=>"admin/users", :action=>"new"}
我想唯一能阻止的攻击者是一个不成熟的攻击者,他爬行并编译了一堆在
admin/
提供系统访问的 Rails 站点,但我认为敢于与管理控制台路径不同并没有什么坏处.
application_controller.rb
before_filter :if_namespace_is_admin?
def if_name_space_is_admin?
#now you should check to see if the namespace is from admin
#now you need namespaces because ruby ns confuse the f'out of me
end
当您在子文件夹中组织控制器时,您必须在控制器顶部添加模块行以匹配“命名空间”。例如,在我的例子中,我希望管理员用户管理制造商,它位于下一个文件夹中: /应用程序/控制器/用户/管理员
然后我有一个控制器继承了基本控制器的遗产,如下所示:
module Users::Admin
class Users::Admin::AdminController < ApplicationController
before_action :authenticate_admin!
private
def authenticate_admin!
unless current_user&.is_admin?
redirect_to root_path, alert: 'You are not authorized to access this page'
end
end
end
end
同样位于/app/controllers/users/admin文件夹中的manufacturer_controller以这种方式启动:
module Users::Admin
class Users::Admin::ManufacturersController < AdminController
before_action :set_manufacturer, only: %i[show edit update]
include Pagy::Backend
@is_new = true
@some_text = 'Hello World'
def index
# @manufacturers = current_user.manufacturers
@q = current_user.manufacturers.ransack(params[:q])
@q.sorts = 'name asc' if @q.sorts.empty?
@pagy, @manufacturers = pagy(@q.result(distinct: true), items: 25)
end
....