標籤:
用MVC做網站的時候,碰到這樣一種情況:
使用者可以匿名訪問某頁面A,頁面可以填寫,然後儲存資料。訪問可以匿名,但是提交的時候會提示登入,然後使用者登入之後才能儲存。
這裡面的問題
1. 使用者匿名訪問頁面A
2. 為提交的表單產生antiforgery token,token中的userName為空白
3. 用ajax登入
4. 使用者提交表單到伺服器,但token驗證失敗。因為當前的token中的userName為空白,與已經登入的userName不匹配。
報錯內容:
提供的防偽標記適用於其他基於聲明的使用者,而不適用於目前使用者
解決思路:
1.登入驗證成功之後,在後台重建有效token並傳遞到前台,然後前台更新token。
Controller:
//todo:登入驗證,成功後執行下面string[] roles = new string[] { }; //具體情況設定HttpContext.User = new GenericPrincipal(new GenericIdentity(userName), roles); //使用者名稱具體設定var ftoken = System.Web.Helpers.AntiForgery.GetHtml().ToString();System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"value=""([^""]+)");var m = r.Match(ftoken);var newToken = m.Groups[1].Value;return Json(new { Success = true, Token = newToken }, JsonRequestBehavior.AllowGet);
View:
$.post("/Account/FloatLogin", { userID: user, pwd: pwd }, function (res) { if (res.Success) { closeDialog(); $("#formID input[name=‘__RequestVerificationToken‘]").val(res.Token); $("#formID").submit(); } else { alert("帳號或密碼錯誤!"); }});
本來思路應該是沒什麼問題,但是實際調試時,仍然報錯:
提供的防偽標記適用於使用者“[email protected]”,但目前使用者為“”
這個思路暫時放下。
2. 登入驗證完成之後,單獨從伺服器擷取一次Token。也就是說把登入和更新Token分作兩個步驟。
Controller:
public int FloatLogin(string userName, string psd){ var success = true;//虛擬碼,這裡驗證身份 var res = success ? 1 : 0;}public string RefreshToken(){ var ftoken = System.Web.Helpers.AntiForgery.GetHtml().ToString(); System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@"value=""([^""]+)"); var m = r.Match(ftoken); var newToken = m.Groups[1].Value; return newToken;}
View:
$.post("/Account/FloatLogin", { userID: user, pwd: pwd }, function (res) { if (res == 1) { closeDialog(); $.get(‘/Account/RefreshToken‘, function (newToken) { $("#formID input[name=‘__RequestVerificationToken‘]").val(newToken); $("#formID").submit(); }); } else { alert("帳號或密碼錯誤!"); }});
這個思路解決了實際的問題。
參考文檔:
http://stackoverflow.com/questions/16815634/reload-antiforgerytoken-after-a-login
http://www.cnblogs.com/jiangzhen/p/3870925.html
http://www.4byte.cn/question/735751/reload-antiforgerytoken-after-a-login.html
留文備用。第一個思路還有哪部分資料沒有寫對,留給以後解決吧。
15.04.14-登入之後重新整理AntiForgeryToken