Orchard CMS Ajax Anti-Forgery Token при входе в систему
Я создаю модуль CMS Orchard, который я тестирую на сайте Orchard 1.3.10. Модуль отображает представление деталей для одного из моих сущностей, и у меня есть кнопка "Избранное", которую я бы хотел щелкнуть и сделать сообщение ajax для действия контроллера, чтобы сохранить объект в качестве избранного в базе данных.
В представлении у меня есть следующий код:
<div style="padding: 10px;">
<span data-id="@Model.Id" id="addFavorite" style="cursor: pointer;">
[Add Favorite]
</span>
</div>
<script type="text/javascript">
$("#addFavorite").click(function () {
alert("here we go...");
$.ajax({
type: "post",
dataType: "",
url: "/orchardlocal/mymodule/stuff/AddFavorite",
data: { id: $(this).data("id") },
success: function (response) {
alert("it worked");
}
});
});
</script>
Мое действие контроллера...
[HttpPost]
public ActionResult AddFavorite(int id)
{
return View();
}
Когда я запустил сайт, не войдя в Orchard, этот код вернётся только в порядке. Если я вхожу в систему и нажимаю "Добавить избранное", я получаю это исключение...
Необходимый токен анти-подделки не был указан или был недействителен.
System.Web.Mvc.HttpAntiForgeryException не был обработан кодом пользователя Сообщение = Требуемый токен анти-подделки не был указан или был недействителен. Источник = System.Web.WebPages ErrorCode = -2147467259 WebEventCode = 0 Трассировки стека: в System.Web.Helpers.AntiForgeryWorker.Validate(контекст HttpContextBase, соль строки) в System.Web.Helpers.AntiForgery.Validate(HttpContextBase httpContext, String salt) в System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext > filterContext) в Orchard.Mvc.AntiForgery.AntiForgeryAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext) в C:\Code\OrchardDev2\src\Orchard\Mvc\AntiForgery\AntiForgeryAuthorizationFilter.cs: строка 37 в System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) в System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) InnerException:
Почему он обрабатывает сообщение по-разному при входе в систему, а не?
Как я могу поставить токен анти-фальсификатора, чтобы избежать этого?
Спасибо,
Brian
Ответы
Ответ 1
ASP.NET MVC по умолчанию не поддерживает генерацию токенов анти-подделки. К счастью, Orchard предоставляет для этого метод расширения.
Вы можете просто изменить свой вызов ajax как есть:
$.ajax({
type: "post",
dataType: "",
url: "/orchardlocal/mymodule/stuff/AddFavorite",
data: {
id: $(this).data("id") },
__RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()'
},
success: function (response) {
alert("it worked");
}
});
Этот метод полезен, так как вам не нужен существующий FORM на вашей странице. Хотя это решение допустимо только в том случае, если javascript отображается из вида Razor.
По-прежнему существует решение, если у вас есть отдельный файл script из вашего представления, который должен сохранить токен анти-подделки внутри переменной javascript, объявленной из представления, а затем использовать его из script:
@using(Script.Head()) {
<script type="text/javascript">
//<![CDATA[
var antiForgeryToken = '@Html.AntiForgeryTokenValueOrchard()';
//]]>
</script>
}
Затем из script:
data: {
id: $(this).data("id") },
__RequestVerificationToken: antiForgeryToken
}
Если нет, то решение, предложенное Дарином, будет правильным путем.
Ответ 2
Как я могу поставить токен анти-фальсификатора, чтобы избежать этого?
Это будет зависеть от того, где скрытое поле, содержащее токен анти-подделки, находится на странице. Например:
$("#addFavorite").click(function () {
var token = $(':input[name="__RequestVerificationToken"]').val();
$.ajax({
type: "post",
dataType: "",
url: "/orchardlocal/mymodule/stuff/AddFavorite",
data: {
__RequestVerificationToken: token,
id: $(this).data("id")
},
success: function (response) {
alert("it worked");
}
});
});