Assuming that I have an API endpoint api.example.com/v1/data and a GET method with @jwt-required similar to this:
from flask_jwt_extended import jwt_required
from flask_restful import Resource
class Data(Resource):
@jwt_required
def get(self):
"""
GET Response message.
"""
return {"message":"important-info", "ts":datetime}, 200
So to GET this message you need to authenticate yourself with a Bearer "access_token" in the request's header.
How could I create an HMAC for this message. Ideally I would like to add the access token, so to check the integrity of the whole message.
So I would like to have an extra field in the returned JSON called checksum with a value hash(whole_message).
You can use Flask's after_request
to register a function that processes the response after it was generated by the view.
For example, to do exactly what you ask for (I am using built-in python's hash
function, you can import/write your own as needed):
@app.after_request
def after_request(response):
data = json.loads(response.get_data())
data['checksum'] = hash(response.get_data())
response.set_data(json.dumps(data))
return response
However, you will have to make sure to always return a dictionary for this to work. Here are a couple alternatives:
1) Include the view's response inside another json, e.g.:
@app.after_request
def after_request(response):
data = json.loads(response.get_data())
data = {
'response': data,
'checksum': hash(response.get_data())
}
response.set_data(json.dumps(data))
return response
2) Add the checksum to the response headers (I would go with this one). E.g.:
@app.after_request
def after_request(response):
response.headers['Checksum'] = hash(response.get_data())
return response
As a final note, if you want to hash the response using the access token, as you state in your question, you can access this token from the request
object, like so:
from flask import request
access_token = request.headers.get('Authorization')
So now you can use access_token
in whatever way you need.