如何通过AngularJs发送AntiForgeryToken实现MVC接口防伪校验
问题根源
- ASP.NET MVC自带的
[ValidateAntiForgeryToken]校验特性,默认仅从application/x-www-form-urlencoded类型的请求表单字段中读取__RequestVerificationToken参数进行校验,你当前将token放在自定义请求头中传递,默认校验逻辑无法识别到token,所以校验失败。 - 额外注意:如果你的请求
Content-Type是application/json,MVC默认也不会从JSON报文体里解析防伪token,同样会触发校验失败。
解决方案
你可以选择以下任意一种方案适配:
方案1:修改后端校验逻辑,支持从请求头读取token
自定义一个继承自ValidateAntiForgeryTokenAttribute的特性类,重写校验逻辑,优先从请求头中取token:
public class ValidateHeaderAntiForgeryTokenAttribute : ValidateAntiForgeryTokenAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.HttpMethod == "POST") { var headerToken = filterContext.HttpContext.Request.Headers["__RequestVerificationToken"]; var cookieToken = filterContext.HttpContext.Request.Cookies[AntiForgeryConfig.CookieName]?.Value; AntiForgery.Validate(cookieToken, headerToken); } else { base.OnAuthorization(filterContext); } } }
之后把你Controller接口上的[ValidateAntiForgeryToken]替换成[ValidateHeaderAntiForgeryToken]即可,原有前端代码不需要改动。
方案2:修改前端传参逻辑,按MVC默认要求传递token
不需要改后端代码,调整AngularJS的请求参数,把token和业务数据一起放到FormData中传递即可:
this.data.Name= $('#txtNm').val(); this.data.Id = $('#Id').val(); var token = angular.element("input[name='__RequestVerificationToken']").val(); // 拼接表单格式参数 var formData = new FormData(); formData.append('__RequestVerificationToken', token); formData.append('Name', this.data.Name); formData.append('Id', this.data.Id); $http({ method: "POST", url: "/Students/Create", data: formData, // 让浏览器自动设置Content-Type,避免边界符丢失 headers: {'Content-Type': undefined }, transformRequest: angular.identity }).then(function (response) { //success }, function (response) { //error });
内容的提问来源于stack exchange,提问作者SYED NAWAZ PRINCE
相关产品推荐
相关产品推荐

