I have several general purpose routes
in my API
:
...
/api/general/user_types
/api/general/dlc_types
...
I want to have the GET
method opened for all users without JWT token
, but the POST
, PUT
and DELETE
methods only accessible when the JWT token
is included in the request.
The problem is that all these methods are allowed on the same route and I serve a different function based on the request method - GET = read
, POST = create
, PUT = update
, DELETE = delete
.
Any way to do this without separating the GET
method into a separate route?
Here is how my routes are declared:
@general_api.route("/user_types", methods=["GET", "POST", "PUT", "DELETE"])
@jwt_required()
def user_types_crud():
instance = ConstantsRoutes(UserTypes, "type")
return crud_routes(request, instance)
The ConstantsRoute
builds a CRUD
class for the UserTypes
table (SQLAlchemy
model), and the crud_routes
function takes a look at the request.method
and returns the proper method
(create
|read
|update
|delete
).
CodePudding user response:
I don't know of a build in decorator
provided by the library. But if using a slightly extended version of the build in decorator
is an option for you, you could define one as followed:
from functools import wraps
from flask import request, current_app
from flask_jwt_extended import verify_jwt_in_request
def jwt_required_for_methods(
optional: bool = False,
fresh: bool = False,
refresh: bool = False,
locations: LocationType = None,
verify_type: bool = True,
protected_methods: list[str] = ["GET", "POST", "PUT", "DELETE"]
) -> Any:
def wrapper(fn):
@wraps(fn)
def decorator(*args, **kwargs):
if request.method in protected_methods:
verify_jwt_in_request(
optional, fresh, refresh,
locations, verify_type
)
return current_app.ensure_sync(fn)(*args, **kwargs)
return decorator
return wrapper
This way the JWT token
is verified only of the request method is in the list
passed as an argument. Protect your route with this decorator
, where needed:
@general_api.route("/user_types", methods=["GET", "POST", "PUT", "DELETE"])
@jwt_required_for_methods(['POST', 'PUT', 'DELETE'])
def user_types_crud():
instance = ConstantsRoutes(UserTypes, "type")
return crud_routes(request, instance)
Hope i could help!