如何在 ajax 中使用 AntiForgeryToken
how to use AntiForgeryToken in ajax
我不知道如何在 ajax 中使用 AntiForgeryToken。
我在 SO 上找到了以下答案,但它们对我不起作用:
- jQuery Ajax calls and the Html.AntiForgeryToken()
- include antiforgerytoken in ajax post ASP.NET MVC
- How to make ajax request with anti-forgery token in mvc
这是我的代码
Html:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.TextBoxFor(model => model.UserName, new { @class = "form-control", id = "UserName", placeholder = @CMS.Resources.Resource.UserName })
@Html.PasswordFor(model => model.Password, new { @class = "form-control", id = "Password", placeholder = @CMS.Resources.Resource.Password })
<button id="LoginButton" class="k-button" type="submit">@CMS.Resources.Resource.Signin</button>
}
JavaScript:
$('#LoginButton').click(function (e) {
if ($('form').valid()) {
var data = { UserName: $('#UserName').val(), Password: $('#Password').val() };
var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
type: 'POST',
traditional: true,
data: JSON.stringify(data),
cache: false,
headers: headers,
dataType: 'json',
url: '@Url.Action("LoginPanel", "Account")',
contentType: "application/json; charset=utf-8",
success: function (status) {
},
error: function (status) {
alert(status);
}
});
}
e.preventDefault();
});
控制器:
[HttpPost, ValidateAntiForgeryToken]
public JsonResult LoginPanel(LoginModel model)
{
LoginStatus status = new LoginStatus();
if (HttpContext.Request.IsAjaxRequest())
{
if (ModelState.IsValid)
{
....
}
}
return Json(status, JsonRequestBehavior.AllowGet);
}
和其他模式的JavaScript代码都试过了。通过将值 __RequestVerificationToken 放在 header 或数据中。错误总是一样的:
所需的 anti-forgery 表单字段“__RequestVerificationToken”不存在。
谢谢。
这对我有用。
提供正确的命名空间和引用,并将下面的代码保存到类似 ValidateJsonAntiForgeryTokenAttribute.cs
的地方,在接受 AJAX POST 请求的控制器操作中,只需使用该属性对其进行修饰所以:
[HttpPost]
[ValidateJsonAntiForgeryToken]
public Task<ActionResult> HandleAjaxCall(string blah) {
}
并且在您的客户端脚本中只包含 @Html.AntiForgeryToken()
某处。在执行 AJAX 调用时,将隐藏字段中的值传递到 AJAX 请求 header... 下面的示例使用 angular,因此请根据客户端进行调整你正在使用的东西...
var details = angular.toJson(...);
var antiForgeryToken = $('input[name="__RequestVerificationToken"]').val();
return $http({
method: 'POST',
headers: { '__RequestVerificationToken': antiForgeryToken },
url: '/ControllerName/HandleAjaxCall',
data: details
});
ValidateJsonAntiForgeryTokenAttribute.cs文件内容:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = new JsonAntiForgeryHttpContextWrapper(HttpContext.Current);
try
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = antiForgeryCookie != null
? antiForgeryCookie.Value
: null;
AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
}
catch (HttpAntiForgeryException ex)
{
//Append where the request url.
var msg = string.Format("{0} from {1}", ex.Message, httpContext.Request.Url);
throw new HttpAntiForgeryException(msg);
}
}
private class JsonAntiForgeryHttpContextWrapper : HttpContextWrapper
{
readonly HttpRequestBase _request;
public JsonAntiForgeryHttpContextWrapper(HttpContext httpContext)
: base(httpContext)
{
_request = new JsonAntiForgeryHttpRequestWrapper(httpContext.Request);
}
public override HttpRequestBase Request
{
get
{
return _request;
}
}
}
private class JsonAntiForgeryHttpRequestWrapper : HttpRequestWrapper
{
readonly NameValueCollection _form;
public JsonAntiForgeryHttpRequestWrapper(HttpRequest request)
: base(request)
{
_form = new NameValueCollection(request.Form);
if (request.Headers["__RequestVerificationToken"] != null)
{
_form["__RequestVerificationToken"] = request.Headers["__RequestVerificationToken"];
}
}
public override NameValueCollection Form
{
get
{
return _form;
}
}
}
}
简单地说,您可以对服务器进行 Ajax 调用(post),
样本Ajax调用:
<script>
function SendData() {
var token = $("[name='__RequestVerificationToken']").val();
var options = {
url: '@Url.Action("Create","Car")',
type: "post",
data: {
__RequestVerificationToken: token,
regNumber: $("#regNumber").val(),
make: $("#make").val(),
model: $("#model").val()
}
};
$.ajax(options);
}
很简单,试试吧...
我不知道如何在 ajax 中使用 AntiForgeryToken。
我在 SO 上找到了以下答案,但它们对我不起作用:
- jQuery Ajax calls and the Html.AntiForgeryToken()
- include antiforgerytoken in ajax post ASP.NET MVC
- How to make ajax request with anti-forgery token in mvc
这是我的代码 Html:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.TextBoxFor(model => model.UserName, new { @class = "form-control", id = "UserName", placeholder = @CMS.Resources.Resource.UserName })
@Html.PasswordFor(model => model.Password, new { @class = "form-control", id = "Password", placeholder = @CMS.Resources.Resource.Password })
<button id="LoginButton" class="k-button" type="submit">@CMS.Resources.Resource.Signin</button>
}
JavaScript:
$('#LoginButton').click(function (e) {
if ($('form').valid()) {
var data = { UserName: $('#UserName').val(), Password: $('#Password').val() };
var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
type: 'POST',
traditional: true,
data: JSON.stringify(data),
cache: false,
headers: headers,
dataType: 'json',
url: '@Url.Action("LoginPanel", "Account")',
contentType: "application/json; charset=utf-8",
success: function (status) {
},
error: function (status) {
alert(status);
}
});
}
e.preventDefault();
});
控制器:
[HttpPost, ValidateAntiForgeryToken]
public JsonResult LoginPanel(LoginModel model)
{
LoginStatus status = new LoginStatus();
if (HttpContext.Request.IsAjaxRequest())
{
if (ModelState.IsValid)
{
....
}
}
return Json(status, JsonRequestBehavior.AllowGet);
}
和其他模式的JavaScript代码都试过了。通过将值 __RequestVerificationToken 放在 header 或数据中。错误总是一样的:
所需的 anti-forgery 表单字段“__RequestVerificationToken”不存在。
谢谢。
这对我有用。
提供正确的命名空间和引用,并将下面的代码保存到类似 ValidateJsonAntiForgeryTokenAttribute.cs
的地方,在接受 AJAX POST 请求的控制器操作中,只需使用该属性对其进行修饰所以:
[HttpPost]
[ValidateJsonAntiForgeryToken]
public Task<ActionResult> HandleAjaxCall(string blah) {
}
并且在您的客户端脚本中只包含 @Html.AntiForgeryToken()
某处。在执行 AJAX 调用时,将隐藏字段中的值传递到 AJAX 请求 header... 下面的示例使用 angular,因此请根据客户端进行调整你正在使用的东西...
var details = angular.toJson(...);
var antiForgeryToken = $('input[name="__RequestVerificationToken"]').val();
return $http({
method: 'POST',
headers: { '__RequestVerificationToken': antiForgeryToken },
url: '/ControllerName/HandleAjaxCall',
data: details
});
ValidateJsonAntiForgeryTokenAttribute.cs文件内容:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
var httpContext = new JsonAntiForgeryHttpContextWrapper(HttpContext.Current);
try
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = antiForgeryCookie != null
? antiForgeryCookie.Value
: null;
AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
}
catch (HttpAntiForgeryException ex)
{
//Append where the request url.
var msg = string.Format("{0} from {1}", ex.Message, httpContext.Request.Url);
throw new HttpAntiForgeryException(msg);
}
}
private class JsonAntiForgeryHttpContextWrapper : HttpContextWrapper
{
readonly HttpRequestBase _request;
public JsonAntiForgeryHttpContextWrapper(HttpContext httpContext)
: base(httpContext)
{
_request = new JsonAntiForgeryHttpRequestWrapper(httpContext.Request);
}
public override HttpRequestBase Request
{
get
{
return _request;
}
}
}
private class JsonAntiForgeryHttpRequestWrapper : HttpRequestWrapper
{
readonly NameValueCollection _form;
public JsonAntiForgeryHttpRequestWrapper(HttpRequest request)
: base(request)
{
_form = new NameValueCollection(request.Form);
if (request.Headers["__RequestVerificationToken"] != null)
{
_form["__RequestVerificationToken"] = request.Headers["__RequestVerificationToken"];
}
}
public override NameValueCollection Form
{
get
{
return _form;
}
}
}
}
简单地说,您可以对服务器进行 Ajax 调用(post),
样本Ajax调用:
<script>
function SendData() {
var token = $("[name='__RequestVerificationToken']").val();
var options = {
url: '@Url.Action("Create","Car")',
type: "post",
data: {
__RequestVerificationToken: token,
regNumber: $("#regNumber").val(),
make: $("#make").val(),
model: $("#model").val()
}
};
$.ajax(options);
}
很简单,试试吧...