我正在尝试为热毛巾SPA应用程序设置注册和登录。我已经基于asp.net single page application template创建了SimpleMembershipFilters和ValidateHttpAntiForgeryTokenAttribute。
你怎么得到的
@Html.AntiForgeryToken()
在Durandal SPA模式下工作的代码。
目前我有一个register.html
<section>
<h2 data-bind="text: title"></h2>
<label>Firstname:</label><input data-bind="value: firstName" type="text" />
<label>Lastname:</label><input data-bind="value: lastName" type="text" />
<label>Email:</label><input data-bind="value: emailAddress" type="text" />
<label>Company:</label><input data-bind="value: company" type="text" />
<br />
<label>Password:</label><input data-bind="value: password1" type="password" />
<label>Re-Enter Password:</label><input data-bind="value: password2" type="password" />
<input type="button" value="Register" data-bind="click: registerUser" class="btn" />
</section>
注册表.js:
define(['services/logger'], function (logger) {
var vm = {
activate: activate,
title: 'Register',
firstName: ko.observable(),
lastName: ko.observable(),
emailAddress: ko.observable(),
company: ko.observable(),
password1: ko.observable(),
password2: ko.observable(),
registerUser: function () {
var d = {
'FirstName': vm.firstName,
'LastName': vm.lastName,
'EmailAddress': vm.emailAddress,
'Company': vm.company,
'Password': vm.password1,
'ConfirmPassword': vm.password2
};
$.ajax({
url: 'Account/JsonRegister',
type: "POST",
data: d ,
success: function (result) {
},
error: function (result) {
}
});
},
};
return vm;
//#region Internal Methods
function activate() {
logger.log('Login Screen Activated', null, 'login', true);
return true;
}
//#endregion
});
在$ AJAX 调用中,我如何传递AntiForgeryToken?以及我如何创建令牌?
4条答案
按热度按时间2izufjch1#
我会阅读this article关于如何使用javascript使用防伪令牌的文章。这篇文章是为WebApi写的,但如果你想的话,它可以很容易地应用到MVC控制器上。
简短的回答是这样的:在您的cshtml视图中:
然后,在asp.net控制器中,您需要验证令牌,如下所示:
你想在头中传递它的原因是,如果你在 AJAX 调用中把它作为parameter data参数传递,在请求的querystring或body中。那么你将很难在所有不同的场景中获得防伪令牌。因为你将不得不反序列化body,然后找到令牌。在头中,它非常一致,并且很容易检索。
**编辑射线
下面是一个操作过滤器的示例,您可以使用该过滤器来确定web api方法的属性,以验证是否提供了antiforgerytoken。
v8wbuo2f2#
获取JS变量中的标记值
然后,只需在**.ajax调用的beforeSend**函数中添加到 AJAX POST头
ctzwtxfj3#
我有点纠结于此,因为现有的两个答案似乎都不适合我的基于热毛巾模板的Durandal SPA应用程序的情况。
我不得不使用埃文拉森和柯蒂斯克的答案的组合,以获得一些工作的方式,我认为它应该。
在我的index.cshtml页面(Durandal支持cshtml和html)中,我在
</body>
标记上方添加了以下内容我按照Evan Larson的建议添加了一个自定义过滤器类,但是我必须修改它以支持单独查找cookie值,并使用__RequestVerificationToken作为名称,而不是RequestVerificationToken,因为这是AntiForgery.GetHtml()提供的名称;
随后,我在我的App_Start/FilterConfig.cs中添加了以下内容
在我的Global.asax下的Application_Start中,我添加了
最后,对于我的 AJAX 调用,我添加了curtisk的input lookup的派生,以便在我的ajax请求中添加一个头,在这个例子中是一个登录请求。
这使得我的所有帖子请求都需要一个验证令牌,该令牌基于由AntiForgery.GetHtml()创建的cookie和隐藏表单验证令牌;
据我所知,这将防止潜在的跨站点脚本攻击,因为攻击站点需要能够提供cookie和隐藏的表单值,以便能够验证自己,这将是更难获得的。
z2acfund4#
如果使用MVC 5,请阅读此解决方案!
我尝试了上面的解决方案,但它们对我不起作用,动作过滤器从来没有达到,我不知道为什么。上面没有提到MVC版本,但我会假设它是版本4。我在我的项目中使用版本5,并结束了以下动作过滤器:
--注意
using System.Web.Mvc
和using System.Web.Mvc.Filters
,而不是http
库(我认为这是MVC v5中发生变化的地方之一。)然后将过滤器
[ValidateJSONAntiForgeryHeader]
应用于您的操作(或控制器),它应该会被正确调用。在
</body>
上方的布局页面中,我有@AntiForgery.GetHtml();
最后,在我的Razor页面中,我执行 AJAX 调用如下: