2010-02-28 15 views
8

İnşa ettiğim sayfa büyük ölçüde AJAX'a bağlıdır. Temel olarak, sadece bir "sayfa" vardır ve her veri aktarımı AJAX üzerinden gerçekleştirilir. Tarayıcı tarafında aşırı hızlı önbelleğe alma, garip problemlere yol açtığından (veriler yeniden yüklenmemiş), POST kullanarak tüm istekleri (aynı zamanda okur) gerçekleştirmem gerekiyor - bu da yeniden yüklemeyi zorluyor.CSRF AJAX Koruması MVC2 kullanarak istekler

Şimdi sayfanın CSRF'ye karşı korunmasını istiyorum. Form sunumu ile, Html.AntiForgeryToken() kullanarak düzgünce çalışır, ancak AJAX-isteği, ben belirteci elle eklemek zorunda kalacak sanırım? Mevcut kutunun dışında bir şey var mı?

Bulunduğum girişimi bu benziyor:

Ben mevcut sihirli yeniden isteriz. Ancak, HtmlHelper.GetAntiForgeryTokenAndSetCookie özeldir ve MVC'de dolaşmak istemiyorum. Bu belirteç doğrulamak için: Diğer seçenek biraz hacky ve çözümsüz daha büyük bir sorun bırakır

public static string PlainAntiForgeryToken(this HtmlHelper helper) 
{ 
    // extract the actual field value from the hidden input 
    return helper.AntiForgeryToken().DoSomeHackyStringActions(); 
} 

gibi bir uzantı yazmaktır? Varsayılan doğrulama uygulaması, form alanlarının kullanılmasına karşı dahili ve kodlanmıştır. Biraz değiştirilmiş bir ValidateAntiForgeryTokenAttribute yazmayı denedim, ancak bu özel bir AntiForgeryDataSerializer kullanıyor ve ben de bunu kopyalamak istemedim.

Bu noktada, evde yetiştirilen bir çözüm bulmak daha kolay görünüyor, ancak bu gerçekten çift kod.

Her türlü öneri nasıl akıllı bir şekilde yapılır? Tamamen açık bir şey eksik miyim?

cevap

10

Sen (bir form içinde oluşması gerekmez) sayfanın herhangi bir yerinde gizli bir alan oluşturmak için geleneksel Html.AntiForgeryToken() yardımcısı kullanmak ve ajax isteği boyunca bunu şunları içerebilir:

var token = $('input[name=__RequestVerificationToken]').val(); 
$.post(
    '/SomeAction', { '__RequestVerificationToken': token }, 
    function() { 
     alert('Account Deleted.'); 
    } 
); 

sunucu tarafında bunu doğrulamak için:

[AcceptVerbs(HttpVerbs.Post)] 
[ValidateAntiForgeryToken] 
public ActionResult SomeAction() 
{ 
    return View(); 
} 

Sayfanızda birden çok jetonunuz varsa, hangisinin ekleneceğini belirtmeniz gerekebilir.

<span id="t1"><%= Html.AntiForgeryToken() %></span> 
<span id="t2"><%= Html.AntiForgeryToken() %></span> 

ve ardından ilgili belirteci seçin:

var token = $('#t1 input[name=__RequestVerificationToken]').val(); 
+0

Parlak varolan yardımcı aynı isimlerle gizli alanları oluşturur gibi bunları iç kapsamlarını yerleştirmek böylece iyi bir seçici yapmak zordur! ÇALIŞIYOR bir cazibe gibi! Gönderilen alanların 'Request.Form' içinde sonuçlanacağını bilmiyorum. Çok düzgün bir seçim ifadesi için +1. Şerefe! – mnemosyn