如何避免ActionController::Parameters更新后的key被permit方法过滤
问题:Rails中修改params键值后permit被过滤
在Rails接口中,直接使用[]=更新ActionController::Parameters的键值后,即便该键已在permit列表中,更新后的值仍会被permit方法过滤,返回nil,且日志标记为未授权参数。
示例场景:传入的foo参数值为"[null,"hello"]",预处理后更新params[:foo],但permit后该参数变为nil:
def temp_api # 预处理参数 if !params[:foo].nil? foo = JSON.parse(params[:foo]) params[:foo] = foo - [nil,''] end p params[:foo] # 正确输出更新后的值 permitted_params = params.permit(:id,:foo) p permitted_params[:foo] # 输出nil(期望保留处理后的值) p permitted_params[:id] # 正常输出传入的id值 end
原因
ActionController::Parameters的[]=操作符会将新赋值的键标记为未许可状态(permitted: false),即使该键原本在许可列表中,permit方法仍会过滤掉这个未授权的新值。
解决方法
方法1:先获取许可参数,再在许可对象上修改
先通过permit拿到原始参数,再在已许可的参数对象上处理并赋值,避免修改原params导致的未授权标记:
def temp_api permitted_params = params.permit(:id, :foo) if permitted_params[:foo].present? processed_foo = JSON.parse(permitted_params[:foo]) - [nil, ''] permitted_params[:foo] = processed_foo end p permitted_params[:foo] # 正确输出处理后的值 p permitted_params[:id] end
方法2:处理后合并到许可参数中
先单独处理得到目标值,再将其合并到已许可的参数哈希中:
def temp_api processed_foo = params[:foo] ? JSON.parse(params[:foo]) - [nil, ''] : nil # 先许可基础参数,再合并处理后的foo permitted_params = params.permit(:id).merge(foo: processed_foo) p permitted_params[:foo] p permitted_params[:id] end
注意事项
- 避免使用
params.permit!(强制许可所有参数),除非你完全信任所有传入参数,否则会带来安全风险。
内容的提问来源于stack exchange,提问作者erenjeager
相关产品推荐
相关产品推荐

