Страница, которую я создаю, зависит в большой степени от Ajax. В основном существует всего одна "страница", и каждая передача данных обрабатывается через Ajax. Так как сверхоптимистическое кэширование на стороне браузера приводит к странным проблемам (данные, не перезагруженные), я должен выполнить все запросы (также чтения) использование POST - который вызывает перезагрузку.
Теперь я хочу предотвратить страницу против CSRF. С представлением формы, с помощью Html.AntiForgeryToken()
работы аккуратно, но в запросе AJAX, я предполагаю, что должен буду добавить маркер вручную? Есть ли что-нибудь out-of-the доступное поле?
Моя текущая попытка похожа на это:
Я хотел бы снова использовать существующее волшебство. Однако 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>
, а затем выбрать соответствующий токен:
var token = $('#t1 input[name=__RequestVerificationToken]').val();