Cha*_*ies 6 python ajax csrf flask
我想对网站上的登录名和注册表单进行 AJAX 化。到目前为止,我一直在使用 WTForms 主要是为了它内置的 CSRF 保护,但是对于这个项目,我觉得它不值得 - 一个额外的抽象层,因此令人沮丧,因为它应该很漂亮简单的。
所以我在 Flask 的安全部分看到了这个片段:
@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
Run Code Online (Sandbox Code Playgroud)
我理解这段代码背后的思考过程。事实上,这一切对我来说都很有意义(我认为)。我看不出有什么问题。
但它不起作用。我对代码所做的唯一更改是将伪函数替换为some_random_string()对os.urandom(24). 到目前为止,每个请求都有 403'd,因为token和request.form.get('_csrf_token')永远不会相同。当我打印出来这是显而易见的-通常它们是不同的字符串,但偶尔的,貌似没有根本的原因,一方或另一方就会None或输出的删减版本os.urandom(24)。显然有些东西不同步,但我不明白它是什么。
您可以轻松flask-wtf享受以下便利:
from flask_wtf.csrf import CsrfProtect
Run Code Online (Sandbox Code Playgroud)
然后在 init 上,要么:
CsrfProtect(app)
Run Code Online (Sandbox Code Playgroud)
或者:
csrf = CsrfProtect()
def create_app():
app = Flask(__name__)
csrf.init_app(app)
Run Code Online (Sandbox Code Playgroud)
然后令牌将在任何时候在应用程序范围内可用,包括通过jinja2:
<form method="post" action="/">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>
Run Code Online (Sandbox Code Playgroud)
(通过文档)
我认为你的问题是 os.urandom 函数。该函数的结果可能包含无法在 html 中正确解析的符号。因此,当您在 html 中插入 csrf_token 并且不进行任何转义时,就会遇到所描述的问题。
怎么修。 尝试在 html 中转义 csrf_token (请参阅文档)或使用其他方法生成 csrf 令牌。例如使用 uuid:
import uuid
...
def generate_random_string():
return str(uuid.uuid4())
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6791 次 |
| 最近记录: |