Thomas Bandt

Über mich | Kontakt | Archiv

ASP.NET MVC Trick 17: AntiForgeryToken() und jQuery.post()

Ich habe im aktuellen Projekt häufiger den Fall, dass ich eine Controller-Action auf zwei Wegen anspreche: einmal über einen Ajax-Request, abgesetzt mit jQuery, und einmal über einen ganz normalen Formular-Roundtrip zum Server. Vor allem bei Letzterem gehört es dazu, diese Requests mit einem so genannten "anti-forgery token" gegen Cross-Site-Attacken abzusichern.

   1:  <form action="<%= Url.Action("deletesubscriptions") %>" method="post">
   2:  <%= Html.AntiForgeryToken() %>
   3:  ...
   4:  </form>

   1:  [HttpPost]
   2:  [ValidateAntiForgeryToken]
   3:  public ActionResult DeleteSubscriptions(string[] subscriptions)
   4:  {
   5:      ...
   6:  }

Im konkreten Beispiel soll man nun also mehrere Subscriptions anhaken und per Klick auf einen Button und anschließendem Roundtrip löschen, als auch eine einzelne Subscription über einen Klick auf einen Button oder Link direkt löschen können. Folgender Aufruf wird dabei aber in einem 500er-Serverfehler enden, den man nur mit Firebug o.ä. zu Gesicht bekommt, und der deshalb auch erstmal sehr verwirrend sein kann.

   1:  function deleteSubscription(subscription) {
   2:   
   3:      if (!confirm('Sind Sie sicher, dass Sie diese Benachrichtigung entfernen möchten?'))
   4:          return;
   5:   
   6:      $.post('/account/subscriptions/deletesubscriptions?subscriptions=' + subscription, null, function () {
   7:          $("#Subscription_" + subscription).fadeOut();
   8:          showAppStatusBar("Die Benachrichtigung wurde entfernt.");
   9:      });
  10:   
  11:  }

Ein Blick in besagtes Firebug zeigt dann auch schon den Fehler auf: beim Post auf die Action wird das angeforderte Token nicht übermittelt, der Zugriff entsprechend blockiert. Die Lösung ist denkbar simpel: man greife sich das Token einfach aus dem DOM und schicke es mit:

   1:  function deleteSubscription(subscription) {
   2:   
   3:      if (!confirm('Sind Sie sicher, dass Sie diese Benachrichtigung entfernen möchten?'))
   4:          return;
   5:   
   6:      var token = $('[name=__RequestVerificationToken]').val();
   7:      var data = { __RequestVerificationToken: token, subscriptions: subscription }
   8:   
   9:      $.post('/account/subscriptions/deletesubscriptions', data, function () {
  10:          $("#Subscription_" + subscription).fadeOut();
  11:          showAppStatusBar("Die Benachrichtigung wurde entfernt.");
  12:      });
  13:   
  14:  }

Im Prinzip eine Kleinigkeit, aber man muss es erstmal wissen.



« Zurück  |  Weiter »