OJ *_*eño 152 asp.net ajax asp.net-mvc csrf asp.net-mvc-3
我在使用ajax的AntiForgeryToken遇到了麻烦.我正在使用ASP.NET MVC 3.我在jQuery Ajax调用和Html.AntiForgeryToken()中尝试了解决方案.使用该解决方案,现在正在传递令牌:
var data = { ... } // with token, key is '__RequestVerificationToken'
$.ajax({
type: "POST",
data: data,
datatype: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
url: myURL,
success: function (response) {
...
},
error: function (response) {
...
}
});
Run Code Online (Sandbox Code Playgroud)
当我删除[ValidateAntiForgeryToken]属性只是为了查看数据(带有令牌)是否作为参数传递给控制器时,我可以看到它们正在被传递.但由于某种原因,A required anti-forgery token was not supplied or was invalid.当我放回属性时,消息仍会弹出.
有任何想法吗?
编辑
antiforgerytoken是在表单中生成的,但我没有使用提交操作来提交它.相反,我只是使用jquery获取令牌的值,然后尝试ajax发布.
这是包含令牌的表单,位于顶部母版页:
<form id="__AjaxAntiForgeryForm" action="#" method="post">
@Html.AntiForgeryToken()
</form>
Run Code Online (Sandbox Code Playgroud)
Dar*_*rov 271
您错误地指定了contentTypeto application/json.
这是一个如何工作的例子.
控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(string someValue)
{
return Json(new { someValue = someValue });
}
}
Run Code Online (Sandbox Code Playgroud)
视图:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
@Html.AntiForgeryToken()
}
<div id="myDiv" data-url="@Url.Action("Index", "Home")">
Click me to send an AJAX request to a controller action
decorated with the [ValidateAntiForgeryToken] attribute
</div>
<script type="text/javascript">
$('#myDiv').submit(function () {
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
url: $(this).data('url'),
type: 'POST',
data: {
__RequestVerificationToken: token,
someValue: 'some value'
},
success: function (result) {
alert(result.someValue);
}
});
return false;
});
</script>
Run Code Online (Sandbox Code Playgroud)
Max*_*Max 61
我做过的另一种(少了javascriptish)方法是这样的:
public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper)
{
var antiForgeryInputTag = helper.AntiForgeryToken().ToString();
// Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="PnQE7R0MIBBAzC7SqtVvwrJpGbRvPgzWHo5dSyoSaZoabRjf9pCyzjujYBU_qKDJmwIOiPRDwBV1TNVdXFVgzAvN9_l2yt9-nf4Owif0qIDz7WRAmydVPIm6_pmJAI--wvvFQO7g0VvoFArFtAR2v6Ch1wmXCZ89v0-lNOGZLZc1" />
var removedStart = antiForgeryInputTag.Replace(@"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", "");
var tokenValue = removedStart.Replace(@""" />", "");
if (antiForgeryInputTag == removedStart || removedStart == tokenValue)
throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect.");
return new MvcHtmlString(string.Format(@"{0}:""{1}""", "__RequestVerificationToken", tokenValue));
}
Run Code Online (Sandbox Code Playgroud)
__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"
Run Code Online (Sandbox Code Playgroud)
$(function () {
$("#submit-list").click(function () {
$.ajax({
url: '@Url.Action("SortDataSourceLibraries")',
data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() },
type: 'post',
traditional: true
});
});
});
Run Code Online (Sandbox Code Playgroud)
它似乎工作!
Abo*_*azl 41
它很简单!当你@Html.AntiForgeryToken()在你的html代码中使用它意味着服务器已经签署了这个页面,并且从这个特定页面发送到服务器的每个请求都有一个标志,阻止黑客发送虚假请求.因此,要让服务器对此页面进行身份验证,您应该执行以下两个步骤:
1.发送一个名为的参数__RequestVerificationToken并获取其值使用代码如下:
<script type="text/javascript">
function gettoken() {
var token = '@Html.AntiForgeryToken()';
token = $(token).val();
return token;
}
</script>
Run Code Online (Sandbox Code Playgroud)
例如,进行ajax调用
$.ajax({
type: "POST",
url: "/Account/Login",
data: {
__RequestVerificationToken: gettoken(),
uname: uname,
pass: pass
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded; charset=utf-8',
success: successFu,
});
Run Code Online (Sandbox Code Playgroud)
和步骤2只是装饰你的行动方法 [ValidateAntiForgeryToken]
在Asp.Net Core中,您可以直接请求令牌,如记录所示:
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}
Run Code Online (Sandbox Code Playgroud)
并在javascript中使用它:
function DoSomething(id) {
$.post("/something/todo/"+id,
{ "__RequestVerificationToken": '@GetAntiXsrfRequestToken()' });
}
Run Code Online (Sandbox Code Playgroud)
您可以添加推荐的全局过滤器,如记录所示:
services.AddMvc(options =>
{
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})
Run Code Online (Sandbox Code Playgroud)
function DeletePersonel(id) {
var data = new FormData();
data.append("__RequestVerificationToken", "@HtmlHelper.GetAntiForgeryToken()");
$.ajax({
type: 'POST',
url: '/Personel/Delete/' + id,
data: data,
cache: false,
processData: false,
contentType: false,
success: function (result) {
}
});
}
public static class HtmlHelper
{
public static string GetAntiForgeryToken()
{
System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), "(?:value=\")(.*)(?:\")");
if (value.Success)
{
return value.Groups[1].Value;
}
return "";
}
}
在Asp.Net MVC中,使用@Html.AntiForgeryToken()Razor时会创建一个隐藏的输入字段,其名称__RequestVerificationToken用于存储令牌。如果要编写AJAX实现,则必须自己获取此令牌并将其作为参数传递给服务器,以便可以对其进行验证。
步骤1:取得凭证
var token = $('input[name="`__RequestVerificationToken`"]').val();
Run Code Online (Sandbox Code Playgroud)
步骤2:在AJAX通话中传递令牌
function registerStudent() {
var student = {
"FirstName": $('#fName').val(),
"LastName": $('#lName').val(),
"Email": $('#email').val(),
"Phone": $('#phone').val(),
};
$.ajax({
url: '/Student/RegisterStudent',
type: 'POST',
data: {
__RequestVerificationToken:token,
student: student,
},
dataType: 'JSON',
contentType:'application/x-www-form-urlencoded; charset=utf-8',
success: function (response) {
if (response.result == "Success") {
alert('Student Registered Succesfully!')
}
},
error: function (x,h,r) {
alert('Something went wrong')
}
})
};
Run Code Online (Sandbox Code Playgroud)
注意:内容类型应为'application/x-www-form-urlencoded; charset=utf-8'
我已经在Github上上传了该项目;您可以下载并尝试。
https://github.com/lambda2016/AjaxValidateAntiForgeryToken
| 归档时间: |
|
| 查看次数: |
144620 次 |
| 最近记录: |