26

Rails アプリに非常に単純な問題があり、洗練された解決策が見つかりません。

次のような URL があります: http://www.example.com/some-path/?foo=123&baz=456

そして、パラメータの1つを処理してリダイレクトしたい: http://www.example.com/some-path/?baz=456

これは、param "foo" を持つすべての URL で一般的に機能するようにしたいので、書き換えコードで "baz" を指定したくありません。

私が欲しいのは次のようなものです:

redirect_to request.path, :params => request.query_parameters.except(:foo)

それがうまくいかないことを除いて。クエリ文字列を手動で正規表現または解析できることはわかっていますが、もっと良い方法があると思います。

4

4 に答える 4

35

これまでに見つけた最良の方法は、次を使用することです。

url_for(params.except(:obsolete_param_name))

アップデート

Grosserが述べたように、攻撃者がホストを URL パラメータとして渡し、ユーザーを別の Web サイトにリダイレクトできるため、これによりアプリケーションにセキュリティ ホールが開かれます。これを防ぐために、rap1dsの提案を使用して、パスのみを使用するように指定できます。

この目的のために、次のようなヘルパー関数を使用できます。

def secure_path_for(params, *excluded_params)
  url_for(params.except(*excluded_params).merge(only_path: true))
end
于 2013-06-19T13:34:43.893 に答える
6

Rails 5 では、これを行おうとすると、サニタイズされていないリクエスト パラメータエラーが発生します。url_for(params.except(:param))

だから私はこれを行うためにこの方法を見つけました:

request_url = request.url # eg. http://qwe.com/path?param1=1&param2=2

query_hash = Rack::Utils.parse_query(URI.parse(request_url).query).except('param1')
url = query_hash.empty? ? request.path : "#{request.path}?#{query_hash.to_query}"

puts url #=> /path?my_param2=2

redirect_to url
于 2016-10-13T17:32:37.360 に答える
6

渡す前に単に params[:foo] を削除するのはどうでしょうか。たぶん次のようなもの:

params.delete[:foo]
redirect_to request.path, :params => params

あまりエレガントではありませんが、1 行追加するだけです。ちなみに Params は、URL の現在のパラメーターを取得するヘルパー メソッドです。

于 2012-11-19T19:59:44.237 に答える
2
uri = URI.parse(request.url)
new_query = uri.query.split("&").reject{|pair|
  k,v = pair.split("=")
  k =~ /^foo\[?/ # reject params named "foo" or "foo[anything"
}.join("&")
# if the new querystring is empty, assign nil instead of "" so we don't
# end up with a solitary question mark at the end of the url.
uri.query = (new_query.empty? ? nil : new_query)
redirect_to uri.to_s

この問題を解決するために、「Rails の方法」で物事を行おうとすると、いくつかの明白ではない問題に遭遇した後、上記の解決策にたどり着きました。例えば:

  • Rails パラメーターの解析では、特別な角かっこの構文を使用するクエリ パラメーターの配列とハッシュが自動的にインスタンス化され?x[a]=1&y[]=2ます{"x"=>{"a"=>"1"}, "y"=>["2"]}。結果として、生の文字列値によるパラメータのフィルタリングは困難になる可能性があります。Rails/rack 以外の CGI モジュールでさえ、param 値の文字列ではなく配列を提供します。
  • Railsparamsハッシュには、GET、POST、および and などのルーティング パラメータの両方が含まれ:action:controllerいるため、それを再利用してクエリ文字列を再構築することはできません。
  • そのため、url_for のような URL ヘルパーはあまり役に立ちません。

これらの問題を考えると、提供されたフレームワーク機能を使用して、現在のリクエストからそのまま再現された純粋で無害なクエリ文字列を取得することができず、単純に 1 つのパラメーターのみを削除することがわかりました。ただし、上記のコードはうまく機能するようです。

于 2013-09-27T19:40:22.383 に答える