Usage¶
Django Configuration¶
After installation,
you’ll need to configure your Django app with some
variables in your settings.py
file.
Make sure the module is installed as an app:
INSTALLED_APPS = (
...
'hawkrest',
)
Make sure the middleware is installed by adding it to your project’s
MIDDLEWARE
or MIDDLEWARE_CLASSES
(Django version < 1.11) setting:
MIDDLEWARE = (
...
'hawkrest.middleware.HawkResponseMiddleware',
)
To protect all your REST views with Hawk, you can make hawkrest the default:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'hawkrest.HawkAuthentication',
),
...
}
Set up the allowed access credentials. Each dict key will be a Hawk ID for
a user who is
allowed to connect to your API. For example, an incoming request with an
ID named script-user
would sign its request using the secret
this should be a long secret string
to make a successful connection.
The credentials dict in your settings file would look like this:
HAWK_CREDENTIALS = {
'script-user': {
'id': 'script-user',
'key': 'this should be a long secret string',
'algorithm': 'sha256'
},
}
You can add each Hawk credential to this dict.
If you need an alternative method for looking up credentials you can set up a
lookup function under the HAWK_CREDENTIALS_LOOKUP
setting. This function
receives a Hawk ID as a parameter and returns a dict containing the
credentials. For example, if you have a HawkUser
model with a key
attribute then you can write a function hawk_credentials_lookup
as follows:
def hawk_credentials_lookup(id):
user = HawkUser.objects.get(some_id=id)
return {
'id': id,
'key': user.key,
'algorithm': 'sha256'
}
and then you would configure it in your settings:
HAWK_CREDENTIALS_LOOKUP = 'yourapi.auth.hawk_credentials_lookup'
Alternately, you can subclass HawkAuthentication
and override the hawk_credentials_lookup()
method. For example:
from hawkrest import HawkAuthentication
class YourHawk(HawkAuthentication):
def hawk_credentials_lookup(self, id):
user = HawkUser.objects.get(some_id=id)
return {
'id': id,
'key': user.key,
'algorithm': 'sha256'
}
and then specify your new class instead in the authentication backend list:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'yourapi.auth.YourHawk',
),
...
}
By default, a generic HawkAuthenticatedUser
instance is returned when valid Hawk credentials are found. If you need another user model, you can set up a lookup function under the HAWK_USER_LOOKUP
setting. This function receives the request and the matched credentials dict as parameters and returns a (user, auth)
tuple as per custom authentication. For example, with a HawkUser
model whose user_id
is included in the credentials dict, you can write a function hawk_user_lookup
as follows:
def hawk_user_lookup(request, credentials):
return HawkUser.objects.get(some_id=credentials['id'])
and then you would configure it in your settings:
HAWK_USER_LOOKUP = 'yourapi.auth.hawk_user_lookup'
Alternately, you can subclass HawkAuthentication
and override the hawk_user_lookup()
method. For example:
from hawkrest import HawkAuthentication
class YourHawk(HawkAuthentication):
def hawk_user_lookup(self, request, credentials):
return HawkUser.objects.get(some_id=credentials['id'])
and then specify your new class instead in the authentication backend list:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'yourapi.auth.YourHawk',
),
...
}
This setting is the number of seconds until a Hawk message expires:
HAWK_MESSAGE_EXPIRATION = 60
To prevent replay attacks, Hawkrest uses the Django cache framework for nonce lookups. You should configure Django with something like memcache in production. By default, Django uses in-memory caching and by default nonce checking will be activated. If you need to disable it for some reason, set this:
USE_CACHE_FOR_HAWK_NONCE = False # only disable this if you need to
Protecting API views with Hawk¶
To protect all API views with Hawk by default, put this in your settings:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'hawkrest.HawkAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
To protect a specific view directly, define it like this:
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView
from hawkrest import HawkAuthentication
class ExampleView(APIView):
authentication_classes = (HawkAuthentication,)
permission_classes = (IsAuthenticated,)
Verification tool¶
Hawkrest ships with a management command you can use to verify your own Hawk API or any other Hawk authorized resource.
Run this from a Django app with Hawkrest installed for more info:
./manage.py hawkrequest --help
If you had secured your Django app using the credentials dict with
key script-user
you could test it out like this:
./manage.py hawkrequest --url http://127.0.0.1:8000/your/view \
--creds script-user -X POST -d foo=bar