2012-06-26 59 views
3

我不熟悉表單如何工作。當表單中的字段不可用時,還可以編輯模型值嗎?

示例場景

比方說,用戶可以創建調查,但他們創造了無法對其進行編輯,但只會增加問題,給他們後。這是通過在Survey上使用編輯操作完成的。

class Survey < ActiveRecord::Base 
    has_many :questions 
    accepts_nested_attributes_for :questions 
end 

class Question < ActiveRecord::Base 
    belongs_to :survey 
    belongs_to :user 
end 

# QuestionsController 

def edit 
    @survey = Survey.find(params[:id]) 
    @survey.questions.build 
end 

def update 
    @survey = Survey.find(params[:id]) 
    @survey.update_attributes(params[:survey]) 
    redirect_to ... 
end 

然後形式應該是:

<%= form_for @survey do |f| %> 
    # No surveys fields on this form! 

    <% f.fields_for :questions do |builder| %> 
    <%= render "question_fields", :f => builder %> 
    <% end %> 

    <%= f.submit "Submit" %> 
<% end %> 

現在,這給調查的價值觀脆弱或開到黑客攻擊,即使我想調查的領域是在創建後無法使用?

一般來說呢?當他們不在表單上時,模型值仍可以編輯嗎?這背後的邏輯是什麼,我怎麼知道他們不能?

謝謝,只是一個試圖學習的新手。

回答

2

是的,即使您沒有爲它們提供字段,仍然可以通過將這些屬性作爲參數提交給表單進行編輯。

爲了防止這種情況發生,您可以使用protect the attributes explicitly(在Rails的更高版本中,這是默認設置)。在你Survey模型中,添加

attr_protected :name # or whatever other attributes that model has 

這可以防止這些屬性的質量分配,無論是創建和更新。要允許創建,你就必須在create行動的SurveyController的明確分配這些屬性:

def create 
    @survey = Survey.new # instead of Survey.new(params[:survey]) 
    @survey.name = params[:survey][:name] 
    @survey.save 
    # etc 
end 

編輯:

由於blackbird07指出,更好的辦法是到白名單,你想要的屬性以允許批量分配,而不是這裏描述的黑名單方法。

+0

有趣,所以'attr_accessible'只是爲了方便?爲了安全起見,我最好在控制器上手動輸入我想要的內容。 – LearningRoR

+0

'attr_accessible'是白名單方法 - 當您使用它時,* not *包含的所有屬性都將受到保護。 「attr_protected」則完全相反。 – Thilo

1

簡而言之:是的,他們可以用精心設計的POST請求進行編輯,使用捲曲工具或通過使用瀏覽器開發工具編輯HTML表單。原因是您使用update_attributes進行更新,它將更新params參數中提供的所有屬性。這就是所謂的批量分配。

建議您列入白名單,你想成爲可編輯的屬性:http://guides.rubyonrails.org/security.html#mass-assignment

另外,強烈建議您閱讀這篇文章關於"Strong parameters: Dealing with mass assignment in the controller instead of the model"

1

您也可以防止質量分配通過把

config.active_record.whitelist_attributes = true 
在你的配置

/application.rb中

現在所有atttrbi tues必須明確標示爲可訪問。它通過在您的應用中爲所有模型創建屬性的空白列表來完成此操作。

+0

爲了提高安全性,在我的模型中執行'attr_accessible#none'也是個好主意嗎? – LearningRoR

+1

是的,這將很好的提醒您已經處理了您的大量作業。 –

相關問題