XSRF 处理
最近在学习 AngularJS 中遇到了一个问题,因为 AngularJS 用的是一个单页面,所以所有的访问其实都是走的 AJAX,而一般的 Web 框架都会有 CSRF 保护,如果是使用 jQuery 来发送 Ajax 请求,在官方文档有给出例子。但是我现在用的 AngularJS,在我的 templates 里只有一个 index.html
文件,所有的页面都是 AngularJS 的ngView
。
在官方给出的 jQuery 例子中,是利用的 Cookie 中存的_xsrf
附加在 AJAX 的参数中,那么问题来了,这个_xsrf
的要首先响应到浏览器中,在 Tornado 中,如果通过常规表单 POST 的话,必须在form
里加上{% module xsrf_form_html() %}
来生成一个_xsrf
的值,通过追踪xsrf_form_html
这个函数,设置_xsrf
是手动的,如果仅有一个index.html
文件,那么就没法显示的设置_xsrf
。
下面是我的解决方法
class BaseHandler(tornado.web.RequestHandler):
def on_finish(self):
self.set_cookie("_xsrf", self.xsrf_token)
这里设置好了_xsrf
,在 AngularJS 中有提供自动处理 XSRF 的方法参考
app.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = "_xsrf";
$httpProvider.defaults.xsrfHeaderName = "X-XSRFToken";
});
POST 参数处理
还有一个问题,在 AngularJS 中,POST 传递的是 application/json 格式的数据参考,所以在 Tornado 中接收到的参数是在 body 中,所以通过RequestHandler.get_arguments()
是获取不到的,所以重新处理一下接收到的数据
class BaseHandler(BaseHandler):
def prepare(self):
args = dict()
if self.request.body:
try:
args = helpers.json_loads(self.request.body)
except ValueError:
pass
self.args = args
接下来在RequestHandler
里使用RequestHandler.args.get()
就可以获得请求的数据了。