Flask JWT 扩展不识别访问令牌,仅当使用 GET 方法时

Flask JWT-extended not recognizing access token, only when GET method is used

大家好!

我正在建立一个网站,但我一直无法发送表格。我的问题是它发送 access_token_cookie,但触发 unauthorized_token_callback。我看到了请求和响应,请求中包含令牌,但代码假装它根本不存在。

我无法理解它,我需要一些好的提示。

这是 JWT 配置,此代码段中不包含密钥:

application.config['JWT_TOKEN_LOCATION'] = ['cookies', 'headers', 'json', 'query_string']
application.config['JWT_COOKIE_SECURE'] = False #! Needs to be changed in production
application.config['JWT_COOKIE_CSRF_PROTECT'] = True
application.config['JWT_CSRF_CHECK_FORM'] = True
application.config['JWT_COOKIE_SAMESITE'] = 'Strict'
application.config['CSRF_COOKIE_NAME'] = 'csrf_token'
application.config['JWT_ACCESS_CSRF_HEADER_NAME'] = ['X-CSRF-TOKEN-ACCESS', 'X-CSRFToken']
application.config['JWT_CSRF_IN_COOKIES'] = True

我正在使用自定义装饰器,它根据用户的角色限制用户访问:

def Xrole_required(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        verify_jwt_in_request()
        role = dth.get_user_by_email(get_jwt_identity()).roles.role_name
        if(role != 'required_role'):
            flash('Xrole required', 'error')
            return Response(render_template('404.html', title='Not Logged In'), 404, mimetype='text/html')
        else:
            return fn(*args, **kwargs)
    
    return wrapper

每当我删除装饰器时,它都会毫无问题地重定向我,但使用它时会说我没有登录。我在其他地方使用这个装饰器并且在那里工作得很好。

有趣的是,这适用于每个 GET 请求,但不适用于其他方法。这是表格,所以你可以看到它:

<form class="form-control" action="{{ url_for('MyEndpoint_name', show='active') }}" method="POST">
  <div class="row pt-2">
    <label for="desc" class="required">Description</label>
    <input id="desc" name="desc" type="text" required class="shadow-sm rounded border">
  </div>
  <div class="row pt-2">
    <label>Text</label>
    <input type="text" class="shadow-sm rounded border">
  </div>
  <div class="row pt-2">
    <label>Number</label>
    <input type='number' value="0" min="0" class="shadow-sm rounded border">
  </div>
    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

这里是处理请求的资源:

class MyResource(Resource):
    
    @Xrole_required
    def post(self, show):
        #here comes the code, this is only for test
        return redirect(url_for('/redirect_page'), 303)

我是不是在某处犯了错误,还是我错过了文档的一些关键部分?

请注意,我不想使用 XMLHttpRequest,因为这太过分了,我已经有很多 js,这些都是简单的形式。

您可能 运行 遇到了 CSRF 问题。确保将 JWT_CSRF_CHECK_FORM 设置为 True 并使用 https://flask-jwt-extended.readthedocs.io/en/stable/api/#flask_jwt_extended.get_csrf_token

在表单的隐藏字段中包含 CRSF 令牌