Move token authentication to X-Api-Token header

Implements #46
This commit is contained in:
Joshua Boniface 2019-07-28 23:12:53 -04:00
parent 717d00cfcf
commit 47c72d9b68
2 changed files with 28 additions and 23 deletions

View File

@ -75,23 +75,26 @@ if config['debug']:
if config['auth_enabled']: if config['auth_enabled']:
api.config["SECRET_KEY"] = config['auth_secret_key'] api.config["SECRET_KEY"] = config['auth_secret_key']
# Authentication decorator function
def authenticator(function): def authenticator(function):
def authenticate(*args, **kwargs): def authenticate(*args, **kwargs):
# Check if authentication is enabled # No authentication required
if not config['auth_enabled']: if not config['auth_enabled']:
return function(*args, **kwargs) return function(*args, **kwargs)
else:
# Session-based authentication
if 'token' in flask.session:
return function(*args, **kwargs)
# Direct token-based authentication
if 'token' in flask.request.values:
if any(token for token in config['auth_tokens'] if flask.request.values['token'] == token['token']):
return function(*args, **kwargs)
else:
return flask.jsonify({"message":"Authentication failed"}), 401
return flask.jsonify({"message":"Authentication required"}), 401 # Session-based authentication
if 'token' in flask.session:
return function(*args, **kwargs)
# Key header-based authentication
if 'X-Api-Key' in flask.request.headers:
if any(token for token in secret_tokens if flask.request.headers.get('X-Api-Key') == token):
return function(*args, **kwargs)
else:
return "X-Api-Key Authentication failed\n", 401
# All authentications failed
return "X-Api-Key Authentication required\n", 401
authenticate.__name__ = function.__name__ authenticate.__name__ = function.__name__
return authenticate return authenticate
@ -106,21 +109,23 @@ def api_auth_login():
if not config['auth_enabled']: if not config['auth_enabled']:
return flask.jsonify({"message":"Authentication is disabled."}), 200 return flask.jsonify({"message":"Authentication is disabled."}), 200
if flask.request.method == 'GET':
return '''
<form method="post">
<p>
Enter your authentication token:
<input type=text name=token style='width:24em'>
<input type=submit value=Login>
</p>
</form>
'''
if flask.request.method == 'POST': if flask.request.method == 'POST':
if any(token for token in config['auth_tokens'] if flask.request.values['token'] in token['token']): if any(token for token in config['auth_tokens'] if flask.request.values['token'] in token['token']):
flask.session['token'] = flask.request.form['token'] flask.session['token'] = flask.request.form['token']
return flask.redirect(flask.url_for('api_root')) return flask.redirect(flask.url_for('api_root'))
else: else:
return flask.jsonify({"message":"Authentication failed"}), 401 return flask.jsonify({"message":"Authentication failed"}), 401
return '''
<form method="post">
<p>
Enter your authentication token:
<input type=text name=token style='width:24em'>
<input type=submit value=Login>
</p>
</form>
'''
@api.route('/api/v1/auth/logout', methods=['GET', 'POST']) @api.route('/api/v1/auth/logout', methods=['GET', 'POST'])
def api_auth_logout(): def api_auth_logout():

View File

@ -16,7 +16,7 @@ Authentication for the API is available using a static list of tokens. These tok
The API provides session-based login using the `/api/v1/auth/login` and `/api/v1/auth/logout` options. If authentication is not enabled, these endpoints return a JSON `message` of `Authentiation is disabled` and HTTP code 200. The API provides session-based login using the `/api/v1/auth/login` and `/api/v1/auth/logout` options. If authentication is not enabled, these endpoints return a JSON `message` of `Authentiation is disabled` and HTTP code 200.
For one-time authentication, the `token` value can be specified to any API endpoint. This is only checked if there is no valid session already established. If authentication is enabled, there is no valid session, and no `token` value is specified, the API will return a JSON `message` of `Authentication required` and HTTP code 401. For one-time authentication, the `token` value can be specified to any API endpoint via the `X-Api-Key` header value. This is only checked if there is no valid session already established. If authentication is enabled, there is no valid session, and no `token` value is specified, the API will return a JSON `message` of `Authentication required` and HTTP code 401.
### Values ### Values
@ -107,7 +107,7 @@ The Flask authentication secret key used to salt session credentials. Should be
* *optional* * *optional*
* *requires* `authentication` -> `enabled` * *requires* `authentication` -> `enabled`
A list of API authentication tokens that can be passed via the `X-Authentication` header to authorize access to the API. A list of API authentication tokens that can be passed via the `X-Api-Key` header to authorize access to the API.
##### `description` ##### `description`