2

ユーザー入力ハッシュ (Rails コントローラーに渡されるパラメーター) の値をチェックしたい。偽のユーザー入力から身を守りたい。Object#try は入力の欠落から私を守ってくれますが、不正な形式の入力はどうなるでしょうか?

単純で危険なケース:

  if params[:credentials][:login] …

明らかに、ユーザーが :credentials の値を提供していない場合、:login を取得しようとする試みは失敗します... Nil にはメソッド :[] がありません。これに対する非常に優れた解決策は、Object#try です。

  if params[:credentials].try(:[], :login) … 

しかし、問題が、ユーザーが不正な形式の資格情報を提供したことである場合はどうなるでしょうか? 特に、ユーザーの 1 人がハッシュではなく配列を渡しました。だから私はまだ例外を取得します、

TypeError: can't convert Symbol into Integer

ボゴスをfalse/nilに変えるtry()のようなものはありますか?

私が来ることができる最も近いのは

  if begin params[:credentials][:login]; rescue; false; end … 

これは少し雑然としていますが、明示的なパラノイアよりもさらにコンパクトでありながら一般的であることは認めます。

  if (params.has_key? :credentials and params[:credentials].is_a? Hash and params[:credentials].has_key? :login) … 
4

1 に答える 1

4

ここでステートメントを使用しないbegin/rescueでください。パフォーマンスにコストがかかり、意図が明確ではありません。try単にrescue nil変装しているのと同じです。

あなたはすべてをチェックしなければなりません、そしてあなたはそれを正しくチェックします。データチェックとロジックを組み合わせるのはちょっと醜いです。

AvdiのConfidentRubyを見たので、コーディング方法を変更しました。私はあなたが次のようなことをすることを提案します(私はあなたのコードを少し単純化しただけです):

def your_action
  checked_params_for_action do
    #safe params here
    #your_controller_code
  end
end

private

def checked_params_for_action(&block)
  if (params[:credentials].is_a?(Hash) && params[:credentials][:login])
    yield
  else
    redirect_to root_path, error: "params malformed"
  end
end
于 2012-08-03T20:28:48.590 に答える