Asp.net
使用 MVC2 的 AJAX 請求中的 CSRF 保護
我正在建構的頁面很大程度上依賴於 AJAX。基本上,只有一個“頁面”,每個數據傳輸都通過 AJAX 處理。由於瀏覽器端過度樂觀的記憶體會導致奇怪的問題(數據未重新載入),因此我必須使用 POST 執行所有請求(也讀取) - 這會強制重新載入。
現在我想阻止頁面針對 CSRF。通過表單送出,使用
Html.AntiForgeryToken()可以很好地工作,但是在 AJAX-request 中,我想我將不得不手動附加令牌?有什麼開箱即用的東西嗎?我目前的嘗試如下所示:
我很想重用現有的魔法。但是,
HtmlHelper.GetAntiForgeryTokenAndSetCookie它是私有的,我不想在 MVC 中亂搞。另一種選擇是編寫一個擴展,如public static string PlainAntiForgeryToken(this HtmlHelper helper) { // extract the actual field value from the hidden input return helper.AntiForgeryToken().DoSomeHackyStringActions(); }這有點 hacky 並留下更大的問題未解決:如何驗證該令牌?預設驗證實現是內部的,並且針對使用表單欄位進行了硬編碼。我試著寫一個稍微修改過的
ValidateAntiForgeryTokenAttribute,但它使用的AntiForgeryDataSerializer是私有的,我也真的不想複製它。在這一點上,提出一個本土解決方案似乎更容易,但這確實是重複的程式碼。
任何建議如何以聰明的方式做到這一點?我錯過了一些完全明顯的東西嗎?
您可以使用正常
Html.AntiForgeryToken()幫助器在頁面某處(不一定在表單內)生成隱藏欄位,並將其包含在 ajax 請求中:var token = $('input[name=__RequestVerificationToken]').val(); $.post( '/SomeAction', { '__RequestVerificationToken': token }, function() { alert('Account Deleted.'); } );要在伺服器端驗證它:
[AcceptVerbs(HttpVerbs.Post)] [ValidateAntiForgeryToken] public ActionResult SomeAction() { return View(); }如果您的頁面上有多個標記,您可能需要指定要包含的標記。由於現有的助手生成具有相同名稱的隱藏欄位,因此很難製作一個好的選擇器,因此您可以將它們放在跨度內:
<span id="t1"><%= Html.AntiForgeryToken() %></span> <span id="t2"><%= Html.AntiForgeryToken() %></span>然後選擇對應的token:
var token = $('#t1 input[name=__RequestVerificationToken]').val();