目前我还没有弄明白CSRF的问题,按我的理解
在页面中使用 @Html.AntiForgeryToken()
在controller层加入[ValidateAntiForgeryToken]标签
就应该OK了
但是这样我的程序总是提示 所需的防伪表单字段“__RequestVerificationToken”不存在
找了很多博客,不是长篇大论,就是不清楚
最后在微软官网查到
感觉讲的比较简单明了
下面是我的代码,如果大家有更好的方法请给我留言!
JS代码如下
<script>
@functions{
public string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
$(function () {
getLanguageID()
});
function getLanguageID() {
var LanguageID = localStorage.getItem("LanguageID");
$('#SelectLanguage').val(LanguageID);
$.ajax({
type: 'POST',
url: '@Url.Action("SetLanguageID","Login")',
headers: {
'RequestVerificationToken': '@TokenHeaderValue()'
},
//contentType: "application/json; charset=utf-8",
data: {
LanguageID: LanguageID,
},
async: false,
dataType: "json",
success: function (data) {
console.log(data)
// window.location.href = "/Login/Login";
},
error: function (message) {
// alert(message);
}
});
}
</script>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using com.aaa.DAL2;
using com.aaa.ViewModels;
namespace aaa.Platform.WEB.Controllers
{
public class LoginController : BaseController
{
//
// GET: /Login/
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
[MyValidateAntiForgeryToken]
public JsonResult SetLanguageID(LanguageModels lm)
{
com.aaa.DAL2.User.SetLanguageID(lm);
return Json("");
}
}
}
using System;
using System.Collections.Generic;
using System.Net;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;
using System.Linq;
using System.Net.Http;
namespace aaa.Platform.WEB.Controllers
{
public class BaseController : Controller
{
}
public class MyValidateAntiForgeryToken : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
var response = filterContext.HttpContext.Response;
if (request.HttpMethod == WebRequestMethods.Http.Post)
{
if (request.IsAjaxRequest())
{
string cookieToken = "";
string formToken = "";
string[] tokens = request.Headers.GetValues("RequestVerificationToken").First().Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
AntiForgery.Validate(cookieToken, formToken);
}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
}
}
下面的代码是我这里调试成功的
现在发现最关键的地方是ajax的 data 中要有 __RequestVerificationToken:token, 加在header中的不起作用
function setLanguageID() {
var token = $('[name="__RequestVerificationToken"]').val();
var LanguageID = $('#SelectLanguage').val();
console.log(LanguageID)
localStorage.setItem("LanguageID",LanguageID)
$.ajax({
type: 'POST',
url: '@Url.Action("SetLanguageID","Login")',
data: {
__RequestVerificationToken:token,
LanguageID: LanguageID,
},
async: false,
dataType: "json",
success: function (data) {
console.log(data);
window.location.href = "/Login/Login";
},
error: function (message) {
// alert(message);
}
});
}
这里是controller代码
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult SetLanguageID(LanguageModels lm)
{
com.canmax.DAL2.User.SetLanguageID(lm);
return Json("");
}
下面是LanguageModels类要有__RequestVerificationToken即可
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace com.aaa.ViewModels
{
public class LanguageModels
{
public int ID { get; set; }
public string LanguageID { get;set;}
public string ItemID { get; set; }
public string ItemText { get; set; }
public string __RequestVerificationToken { get; set; }
}
}