跨站請求僞造:xsrf或csrf。
tornado開啓xsrf_cookies驗證。
xsrf_cookies=True
tornado的RequestHandler中的有一個check_xsrf_cookie()方法。它會從請求中獲取_xsrf參數,並提供校驗。
前端模板中添加{% raw xsrf_form_html() %}。
def xsrf_form_html(self):
return '<input type="hidden" name="_xsrf" value="' + \
escape.xhtml_escape(self.xsrf_token) + '"/>'
ajax post,從cookie中獲取_xsrf。
function getCookie(name) {
var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");
return r ? r[1] : undefined;
}
function set_xsrf(data){
var secure_key = getCookie("__xsrf") || "";
if (isNotEmpty(secure_key)) {
data["__xsrf"] = secure_key;
}
return data;
}
var data = {'name': 'JianW'};
set_xsrf(data);
$.ajax({
url : url,
data : data,
dataType : "JSON",
type : "POST",
async : false,
success : function(ret) {
code_list.push(ret.code);
}
});
後臺RequestHandler中check_xsrf_cookie方法。
def check_xsrf_cookie(self):
token = (self.get_argument("_xsrf", None) or
self.request.headers.get("X-Xsrftoken") or
self.request.headers.get("X-Csrftoken"))
if not token:
raise HTTPError(403, "'_xsrf' argument missing from POST")
_, token, _ = self._decode_xsrf_token(token)
_, expected_token, _ = self._get_raw_xsrf_token()
if not _time_independent_equals(utf8(token), utf8(expected_token)):
raise HTTPError(403, "XSRF cookie does not match POST argument")
在__execute()方法中,有如下代碼片段。若開啓了xsrf_cookies則會來執行之前的check_xsrf_cookie()
# If XSRF cookies are turned on, reject form submissions without
# the proper cookie
if self.request.method not in ("GET", "HEAD", "OPTIONS") and \
self.application.settings.get("xsrf_cookies"):
self.check_xsrf_cookie()
可以通過繼承Basehandler並重寫check_xsrf_cookie(),來對部分請求去除xsrf_cookie防禦,如去除/rest開頭的請求的校驗。
def check_xsrf_cookie(self):
if not self.request.path.startswith('/rest'):
...