没有Rails如何实现强参数保护?

How to achieve strong parameter protection without Rails?

我正在使用 Goliath + Grape + Active Record 4.2 + Active Record Migrations 开发样板 Web 应用程序。这是我的迁移文件

# db/migrate/20150519063210_create_albums.rb
class CreateAlbums < ActiveRecord::Migration
  def change
    create_table :albums do |t|
      t.string :name
      t.string :artist
      t.string :genre
      t.date :published_at
    end
  end
end

还有我的模特

# app/models/Album
class Album < ActiveRecord::Base
end

还有葡萄 API

class ApiV1 < Grape::API
  version 'v1', using: :path
  format :json

  resource 'albums' do
    get '/' do
      Album.all
    end

    post '/' do
      Album.create(params[:album])  # <-- raises ActiveModel::ForbiddenAttributesError
    end
  end
end

当我用一些参数调用 POST /v1/albums/ 时,应用程序总是引发 ActiveModel::ForbiddenAttributesError。似乎 ActiveRecord 想要 ActionController::Parameters 作为参数,但 Grape 给了它 Hashie::Mash

我已经尝试实现一个简单的 Rack 中间件来将 env['params']Hash 转换为 ActionController::Parameters 并在 Goliath::Rack::Params 之后使用它,但是 Grape 只是清理它当辅助方法 params 被调用时输出。我也尝试实现并使用 Grape 中间件来做同样的事情并得到相同的结果。

是否有任何解决方案,或者我只需要降级到 ActiveRecord 3?

您可以使用您的参数创建一个助手来生成 ActionController::Parameters 的实例:

require 'action_controller/metal/strong_parameters' 

class ApiV1 < Grape::API
  version 'v1', using: :path
  format :json

  helpers do
    def albums_params
      ActionController::Parameters.new(params).require(:album).permit(:attr1, :attr2)
    end
  end

  resource 'albums' do
    get '/' do
      Album.all
    end

    post '/' do
      Album.create(albums_params)
    end
  end
end

或者您可以使用 hashie-forbidden_attributes gem.