Flask中AJAX身份验证的CSRF保护 [英] CSRF protection on AJAX authentication in Flask

查看:338
本文介绍了Flask中AJAX身份验证的CSRF保护的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想同时对网站上的登录名和注册表进行AJAX认证。到目前为止,我一直主要将WTForms用于其内置的CSRF保护,但是对于这个项目,我并不认为这是值得的-额外的抽象层,因此也令人沮丧,因为它应该很漂亮简单。

I'd like to AJAXify both a login and a signup form on a site. Up to now I've been using WTForms mainly for its built-in CSRF protetion, but for this project I didn't feel like it was worth it -- an extra layer of abstraction, and therefore frustration, for something that should be pretty simple.

所以我遇到了此代码段在Flask的安全性部分:

So I came across this snippet on Flask's security section:

@app.before_request
def csrf_protect():
    if request.method == "POST":
        token = session.pop('_csrf_token', None)
        if not token or token != request.form.get('_csrf_token'):
        abort(403)

def generate_csrf_token():
    if '_csrf_token' not in session:
        session['_csrf_token'] = some_random_string()
    return session['_csrf_token']

app.jinja_env.globals['csrf_token'] = generate_csrf_token

我了解此代码背后的思考过程。实际上,这对我来说完全有意义(我认为)。我看不出有什么问题。

I understand the thought process behind this code. In fact, it all makes perfect sense to me (I think). I can't see anything wrong with it.

但是它不起作用。我对代码所做的唯一更改是将伪函数 some_random_string()替换为对 os.urandom(24)。到目前为止,每个请求都有403个请求,因为 token request.form.get('_ csrf_token')从未相同。当我打印它们时,这很明显-通常它们是不同的字符串,但偶尔,而且似乎没有根本原因,一个或另一个将是 None 或截短的版本 os.urandom(24)的输出。显然有些东西不同步,但是我不明白它是什么。

But it doesn't work. The only thing I've changed about the code is replacing the pseudofunction some_random_string() with a call to os.urandom(24). Every request has 403'd so far because token and request.form.get('_csrf_token') are never the same. When I print them this becomes obvious -- usually they're different strings, but occasionally, and seemingly with no underlying reason, one or the other will be None or a truncated version of the output of os.urandom(24). Obviously something out of sync, but I'm not understanding what it is.

推荐答案

您可以获得<$ c的便利$ c> flask-wtf ,而不需要任何负担,也无需自己动手:

You can get the convenience of flask-wtf without all the heaviness, and without rolling your own:

from flask_wtf.csrf import CsrfProtect

然后在初始化时,要么:

then on init, either:

CsrfProtect(app)

或:

csrf = CsrfProtect()

def create_app():
    app = Flask(__name__)
    csrf.init_app(app)

随后,该令牌将在整个应用范围内可用点,包括通过 jinja2

The token will then be available app-wide at any point, including via jinja2:

<form method="post" action="/">
  <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

(通过文档

这篇关于Flask中AJAX身份验证的CSRF保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆