flaskhmac

Provides easy integration of the HMAC signatures for your REST Flask Applications.


Keywords
Flask, HMAC, REST, Views
License
Unlicense
Install
pip install flaskhmac==1.2.1

Documentation

Flask-HMAC

circle downloads version license

This module provides an authentication to Flask routes. The intended use case is for use with REST APIs. It's simply designed to check that a client is entitled to access a particular route in a Flask application, based on the fact that it must possess a copy of the secret key.

Usage

Server

app = Flask(__name__)
app.config['HMAC_KEY'] = 's3cr3tk3y'  # define the secret key in an app config


@app.route("/no_auth_view")
def no_auth_view():
    return "no_auth_view"


@app.route("/hmac_auth_view")
@hmac.auth()  # decorate view
def hmac_auth_view():
    return "hmac_auth_view"

@app.route("/hmac_auth_view")
@hmac.auth(only=["foo"])  # decorate view, only allows foo client access
def hmac_auth_view():
    return "hmac_auth_view"

Client

Call without payload

sig = hmac.make_hmac()  # generate signature
response = requests.get(
    '/hmac_auth_view',
    headers={hmac.header: sig}
)

You can also use multiple keys between different applications. Secret keys are stored in HMAC_KEYS in the app settings as a dictionary:

app.config['HMAC_KEYS'] = {
    'aservice': 'akey',
    'bservice': 'bkey'
}

Then the secret key has to generated with make_hmac_for method.

hmac.make_hmac_for('aservice', request_data)  # data is optional

# signature validation for multiple keys

hmac.validate_service_signature(request)

Call with payload

Request payload has to be used as a data for HMAC generation.

data = json.dumps({'foo': 'boo'})

sig = hmac.make_hmac(data)  # generate signature
response = requests.post(
    '/hmac_auth_view',
    data=data,
    headers={hmac.header: sig}
)

You can define custom errors overwriting abort method:

class MyHmac(Hmac):

    def abort(self):
        message = {'status': '403', 'message': 'not authorized'}
        response = jsonify(message)
        response.status_code = 403
        return response

For HMAC auth of all views you can use Flask's before_request:

@app.before_request
def before_request():
    try:
        hmac.validate_signature(request)
    except HmacException:
        return abort(400)

Generate signature for/from another application:

sig = make_hmac(self, data, key=another_app_key)