我正在开发一个ASP.NET MVC Web应用程序。我正在使用AngularJS。但由于CSRF验证,我在向服务器提交表单时遇到问题。首先,我是AngularJS的新手。
在AngularJS中,我在按钮点击事件
上提交这样的表格angular.module('loginApp', ['ui.bootstrap', 'blockUI']).controller('loginController', function ($scope) {
$scope.loginFormData = { }
$scope.submitLoginForm = function()
{
$http.post("url", $scope.loginFormData, function (response) {
})
}
});
在服务器端,我进行CSRF验证以形成帖子
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<JsonResult> Login(LoginViewModel model)
{
//Do other stuff
}
这是我的表单HTML:
@Html.AntiForgeryToken()
<div class="lock-container">
<div class="panel panel-default text-center paper-shadow" data-z="0.5">
<div class="panel-body">
<div class="form-group">
<div class="form-control-material">
<input class="form-control" ng-model="username" type="text" placeholder="Username">
@Html.LabelFor(x => x.UserName)
</div>
</div>
<div class="form-group">
<div class="form-control-material">
<input class="form-control" ng-model="password" type="password" placeholder="Enter Password">
@Html.LabelFor(x=>x.Password)
</div>
</div>
<button ng-click="submitLoginForm()" class="btn btn-primary">Login <i class="fa fa-fw fa-unlock-alt"></i></button>
</div>
</div>
</div>
实际上它不是一种形式。我只是基本上用Ajax提交数据。您注意到顶部的@ Html.AntiForgeryToken()。当我在浏览器中检查时,我可以看到这样。
我想要做的是我想获得该令牌值并发送如下的$ http帖子。
$http.post("url",{ "_RequestVerificationToken": $scope.csrfToken }, function (response) {
})
如果我像上面那样发送,csrf验证将在服务器上成功。我怎样才能实现它AngularJS?
答案 0 :(得分:0)
您可以在标头中传递这些值,而不是正文内容。这可以针对该模块全局完成。请参阅以下链接。
angular.module('app')
.run(function ($http) {
$http.defaults.headers.common['X-XSRF-Token'] =
angular.element('input[name="__RequestVerificationToken"]').attr('value');
});
请参阅此链接
AngularJS Web Api AntiForgeryToken CSRF
https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks
答案 1 :(得分:0)
将令牌添加到FormData
var formData = new FormData();
formData.append("__RequestVerificationToken", token);
formData.append("UserName", $scope.kullaniciAdi);
formData.append("Password", $scope.sifre);
$http({
method: 'POST',
url: '/Login/Login',
data: formData,
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}).then(function successCallback(response) {
}, function errorCallback(response) {
});
答案 2 :(得分:0)
要使csrf验证在服务器上成功进行,您需要在服务器端进行一些修改。
您可以在服务器端创建自定义过滤器属性,以验证您的防伪令牌。
创建一个类,并从System.Web.MVC提供的 ActionFilterAttribute 继承它。确保不要使用Web API命名空间。
using System;
using System.Web.Helpers;
using System.Web.Mvc;
namespace CustomFilters.Web.Filters
{
public class MVCAntiForgeryTokenValidatorAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}
if (filterContext.HttpContext.Request.HttpMethod != "GET")
{
var header = filterContext.HttpContext.Request.Headers.Get("_RequestVerificationToken");
var cookieName = AntiForgeryConfig.CookieName; // this also same as the _RequestVerificationToken
var tokenCookie = filterContext.HttpContext.Request.Cookies.Get(cookieName);
var tokenHeader = string.Empty;
if (!string.IsNullOrEmpty(headers))
{
tokenHeader = header;
}
AntiForgery.Validate(tokenCookie != null ? tokenCookie.Value : null, tokenHeader);
}
base.OnActionExecuting(filterContext);
}
}
}
然后您需要使用上面创建的自定义属性修改方法
[HttpPost]
[AllowAnonymous]
[MVCAntiForgeryTokenValidator]
public async Task<JsonResult> Login(LoginViewModel model)
{
//Do other stuff
}
然后您完成了。当您的方法被angularJs服务方法击中时,在执行类方法之前。它将首先验证防伪令牌。