Rails 5.1 路由:动态 :action 参数

19
Rails 5.0.0.beta4引入了一个警告,在包含动态 :action 和 :controller 片段的路由中:
DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 5.1. 

这个PR的提交信息 表示:

在 config/routes.rb 中允许通过路径指定 :controller 和 :action 值一直以来都是 Rails 中一些问题的潜在根源,导致了一系列的安全版本发布。鉴于此,显式地将控制器和操作添加到白名单中比试图对“坏”值进行黑名单或清理更好。

如何“添加到白名单”一组操作参数?我在我的路由文件中有以下内容,它们正在引发弃用警告:

namespace :integrations do
  get 'stripe(/:action)', controller: 'stripe', as: "stripe"
  post 'stripe/deactivate', controller: 'stripe', action: 'deactivate'
end

显而易见的答案似乎是明确定义每个动作,但在具有许多自定义操作的控制器中,这似乎很繁琐。也许这仍然是最佳实践,不是吗? - Ryenski
3个回答

25

虽然有点麻烦,但最佳方法似乎是明确定义路由:

namespace :integrations do
  namespace 'stripe' do
    %w(auth webhook activate).each do |action|
      get action, action: action
    end
  end
  post 'stripe/deactivate', controller: 'stripe', action: 'deactivate'
end

1
只是一个小注释。在 get action, action: action 中,你可以省略 action,因为 Rails 默认使用与 get 相同名称的 action。因此,get action 就足够了。 - 3limin4t0r

4
不同于你的情况,但我做了这个:
class PagesController < ApplicationController
  def index
    render params[:path]
  end
end

路由:

get ':path', to: 'pages#index'

如果我想要一个嵌套路径,我会使用*

get '*path', to: 'pages#index'

这种方法可能不安全 - http://brakemanscanner.org/docs/warning_types/dynamic_render_paths/ - Brad Werth
@BradWerth 我知道这种代码可能存在安全隐患,但在这种情况下,文章没有给出示例,params[:path]是一个字符串,它只会查找与路径匹配的文件。 - sites
谢谢,这也很难理解,我想要防止这种情况,可以做一些像 render params[:path] if File.exists?(Rails.root.join 'app', 'views', 'pages', params[:path]) && !params[:path].starts_with?('_') 这样的事情... 嗯,但我想这就是他们弃用动态操作的原因... 在许多情况下。 - sites
一个简单的选择是只接受路径中的字母 params[:path][/\A\w+\z/],我认为局部视图不会被渲染,据我记得 render '_some' 并不起作用。 - sites
使用以下代码检查模板是否存在。第三个参数指定您是否需要部分。lookup_context.template_exists?(params[:path], "pages", false)API文档 - timeon
显示剩余3条评论

-4
它的工作原理如下:
get 'stripe(/:action)', controller: 'stripe', action: :action, as: "stripe"

4
这正是已被弃用的内容。 - James Moore
@JamesMoore 有没有关于已弃用的文档? - Frank Fang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接