I am using Flask-JWT-Extended (https://pypi.org/project/Flask-JWT-Extended/) to secure my flask app. The jwt_required
decorator takes optional
as an argument. Nevertheless my flask app is created inside a class and I cannot set the optional
argument before instantiating the class.
Here is what I tried:
from flask import Flask, jsonify
from flask_jwt_extended import jwt_required, JWTManager
jwt_optional = False
class Node:
def __init__(self, name: str, key: str, jwt_opt: bool = False):
self.app = Flask(name)
self.app.config['SECRET_KEY'] = key
global jwt_optional
jwt_optional = jwt_opt
self.app.add_url_rule(rule='/get_token',
endpoint='get_token',
view_func=self.get_token,
methods=['GET'])
@jwt_required(optional=jwt_optional)
def get_token(self):
print('Token success')
return jsonify({'msg': 'Token success'})
if __name__ == '__main__':
node = Node('Test Node', key='unsafe', jwt_opt=True)
app = node.app
app.config['TESTING'] = True
jwt = JWTManager(app=app)
test_app = app.test_client()
response = test_app.get('/get_token')
print(response.json)
I guess it's obvious that it does not work since the decorator is evaluated before I change the global variable.
Is it possible to make the token optional at runtime?
I also had to deal with the case of optional JWTs. What I ended up doing is putting the decorator on top of a generic function and then simply call that function during the route itself - or skip it, in case jwt_optional is True
jwt_optional = True
@jwt_required()
def jwt_protection():
pass
# ...
class Node:
# ...
def get_token(self):
if jwt_optional is False:
jwt_protection()
print('Token success')
return jsonify({'msg': 'Token success'})
I thought this was a simple workaround, it might also help in your situation