首先先簡述一下CSRF:
CSRF是Cross Site Request Forgery的縮寫(也縮寫為XSRF),直譯過來就是跨站請求偽造的意思,也就是在用戶會話下對某個CGI做一些GET/POST的事情——這些事情用戶未必知道和願意做,你可以把它想做HTTP會話劫持。
網站是通過cookie來識別用戶的,當用戶成功進行身份驗證之后瀏覽器就會得到一個標識其身份的cookie,只要不關閉瀏覽器或者退出登錄,以后訪問 這個網站會帶上這個cookie。如果這期間瀏覽器被人控制着請求了這個網站的url,可能就會執行一些用戶不想做的功能(比如修改個人資料)。因為這個 不是用戶真正想發出的請求,這就是所謂的請求偽造;呵呵,因為這些請求也是可以從第三方網站提交的,所以前綴跨站二字。
當你采用有"_xrsf"防止攻擊做項目的時候,你會發現如果采用ajax提交表單的話會出現“ _xsrf' argument missing from POST” 的錯誤。
首先我們可能會想到在是因為表單里面input標簽的type屬性不是submit,而是button(用於aja提交)。所以可以將其該為submit是可以解決的,但是這會讓ajax失去意義,因為攔不住form表單的action操作,也許可以在form標簽里面加上onsubmit="return user_login();":
1 <form action="/check_login_action" method="post" onsubmit="return user_login();"> 2 <dl><h2> 用戶登錄</h2><hr> 3 <dt>賬號:<input id="user_name" name="user_name" type="text" placeholder="輸入賬號"/> <a href="register_user.html">注冊賬戶</a></dt> 4 <dt>密碼:<input id="user_password" name="user_password" type="password" placeholder="輸入密碼"/>
<a href="find_password.html">找回密碼</a></dt> 5 {% raw xsrf_form_html() %} 6 <dt><input type="submit" value="登錄" ></dt> 7 </dl> 8 </form>
但是ajax的優勢也會被覆蓋掉;所以如果一定要采用ajax的話(至少可以很好的操作回顯的值),可以在js中拿到這個xrsf里面的值傳到后端就解決了:
function user_login(){ var _xsrf = $("input[name='_xsrf']").val(); var user_name = $("#user_name").val(); var username = check(1, user_name); if(username.split('#')[0]=='F'){ alert(username.split('#')[1]); } else{ var user_password = $("#user_password").val(); var userpass = check(2, user_password); if(userpass.split('#')[0]=='F'){ alert(userpass.split('#')[1]); } else{ var xmlhttp; if(window.XMLHttpRequest){ xmlhttp = new XMLHttpRequest(); } else{ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4 && xmlhttp.status == 200){ var json_login = eval("("+ xmlhttp.responseText +")"); if(json_login.returnedjson.infostatus == 'T'){ alert(json_login.returnedjson.infomsg); window.location.href = "/personal_account_temp"; //obj.action = "/check_login_action"; } else{ alert(json_login.returnedjson.infomsg); $("#user_name").val(""); $("#user_password").val(""); $("#user_name").focus(); } } } var user_mess ="user_name=" + encodeURIComponent(user_name) + "&user_password=" + encodeURIComponent(user_password) + "&_xsrf=" + _xsrf;
//傳給后端,后端會自動的去接收 xmlhttp.open("post", "/check_login_action", true); xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); xmlhttp.send(user_mess); } } }
問題解決。。。