在我的代码中,当用户登录时,凭据作为Ajax中的Json对象发送(AntiForgeryToken隐藏字段值也在Json内发送),服务器验证用户,应用FormsAuthentication.SetAuthCookie(),并返回Json结果,包含一些用户特定的数据.这样,我可以在登录时避免整页刷新.
问题是,对服务器的每个后续Ajax请求现在都在ValidateAntiForgeryTokenAttribute上失败,因为它现在需要一个与防伪cookie不兼容的防伪标记.
如何将有效的防伪令牌放入客户端的隐藏字段中,以便登录后的每个Json请求都会成功?
我试图手动获取一个新的隐藏字段标记(在动作上使用AntiForgery.GetHtml(),提取标记字符串本身,将其返回到Json中的客户端并在JavaScript中手动将其置于防伪隐藏字段中)但是它不起作用 – 后续的Ajax调用在服务器上的ValidateAntiForgeryTokenAttribute上失败.
实际上,每次调用AntiForgery.GetHtml()(实质上是Html.AntiForgeryToken()帮助程序所做的)都会产生一个不同的令牌,这会使前一个令牌失效.
我还尝试设置HttpContext.User = new GenericPrincipal(new GenericIdentity(email),null);详见here,但它不起作用.
注意:This solution对我不起作用,因为我的具体情况:Ajax登录更改了服务器上的用户身份,因此登录前生成的每个令牌都无效; this solution也不适用,因为它解决了另一个问题.
解决方法
您应该能够通过以下方式轻松获取要替换的令牌实例:
var token = $('input[name=""__RequestVerificationToken""]');
编辑
重读几次后 – 我提问
如果用户没有登录,为什么你会在表单上有一个令牌.你允许在没有登录和登录的情况下“操作”相同的表单?即使在这种情况下网络上的大多数网站都将重定向登录.我理解正确吗?如果是这样,您可能需要考虑在此处跳过令牌或对未经身份验证的用户使用第二种类型的令牌.我相信你说的是一个未经身份验证的用户已经可以在应用程序中提交一些内容 – 如果我理解正确的话 – 再次进行身份验证.