会话更改未反映

时间:2019-12-04 17:45:46

标签: http session cookies form-submit

我正在尝试实现基于令牌的提交跟踪机制,以避免表单已多次提交。我的想法是生成令牌,并在表单生成后将其存储在会话中。首次检测到提交动作时,令牌将被吊销,因此,如果用户多次提交,则以下操作将不被接受,因为无法再找到有效的令牌。所以我的Python代码是这样的:

用于生成表单的代码:

from flask import Flask, render_template, request, Response, make_response, session

@app.route('/form')
def form():
    ...
    # Create token and store in session
    submit_tracking_id = uuid.uuid1()
    session['submit_tracking_id'] = submit_tracking_id
    ...
    # A copy of token would be stored in the cookie
    resp.set_cookie('submit_tracking_id', str(submit_tracking_id))
    return resp

表单动作服务代码:

@app.route('/action', methods=['POST'])
def action():
    ...
    # Check token by compare cookie and session.
    if 'submit_tracking_id' in request.cookies:
        if uuid.UUID(request.cookies.get('submit_tracking_id')) == session.pop('submit_tracking_id', None):
            # Long time processing...
            ...
        else:
            ...
     ...

我希望session.pop会在第一次检索到时撤消'submit_tracking_id'。但是现实让我感到惊讶的是,如果我在if命令下面的下一行(在执行session.pop之后)设置一个断点来暂停上一个过程,并立即触发另一个提交,第二个请求仍将能够获得令牌!在对比方面,如果我在第一个请求完全完成后触发第二个请求,则第二个请求不会被捕获。为什么会话在上一个请求返回之前没有反映出更改?

用于查询服务的客户端javascript如下:

const test_form = document.forms.namedItem("test_form");
test_form.addEventListener('submit', ev => {
    ev.preventDefault();
    __submit(__read_form_data('test_form')).then(html => {
        document.getElementById("result").innerHTML = html
    })
})

__submit = (data) => {
    return fetch('/action', {
        method: 'POST',
        body: data
    }).then(response => {
        if(response.status == '200') {
            return response.text()
        } else
            return ''
    })
}

有没有人可以解释会话存储的工作原理?实施该机制的正确方法是什么?

0 个答案:

没有答案