跨站请求伪造: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'):
...