Django APIs
axioms-drf-py 
axioms-drf-py is a Python package for Django Rest Framework (DRF) which helps you to secure your DRF APIs using Axioms Authentication and Authorization.
Prerequisite
- Python 3.7+
- An Axioms client which can obtain access token after user's authentication and authorization and include obtained access token as bearer in
Authorizationheader of all API request sent to Python/Flask application server.
Install SDK
Install axioms-drf-py in you DRF API project,
pip install axioms-drf-py
Add .env file
Create a .env file in your main Django app and add following configs,
.env
AXIOMS_DOMAIN=<your-axioms-slug>.axioms.io
AXIOMS_AUDIENCE=<your-axioms-resource-identifier-or-endpoint>
Load Config
In your Django project settings.py,
settings.py
import os
import environ
env = environ.Env(
# set casting, default value
DEBUG=(bool, False)
)
# reading .env file
environ.Env.read_env()
AXIOMS_DOMAIN=env('AXIOMS_DOMAIN')
AXIOMS_AUDIENCE=env('AXIOMS_AUDIENCE')
Guard Your API Views
Use authentication and permission classes to guard you API views.
| Class | Description | Parameters |
|---|---|---|
axioms_drf.authentication.HasValidAccessToken | Checks if API request includes a valid bearer access token as authorization header. Check performed includes: token signature validation, expiry datetime validation, and token audience validation. | |
axioms_drf.permissions.HasRequiredScopes | Check any of the given scopes included in scope claim of the access token. | access_token_scopes; An array of strings as conditional OR representing any of the allowed scope or scopes for the view as parameter. For instance, to check openid or profile pass ['profile', 'openid'] as parameter. |
axioms_drf.permissions.HasRequiredRoles | Check any of the given roles included in roles claim of the access token. | access_token_roles; An array of strings as conditional OR representing any of the allowed role or roles for the view as parameter. For instance, to check sample:role1 or sample:role2 roles you will pass ['sample:role1', 'sample:role2'] as parameter. |
axioms_drf.permissions.HasRequiredPermissions | Check any of the given permissions included in permissions claim of the access token. | access_token_permissions; An array of strings as conditional OR representing any of the allowed permission or permissions for the view as parameter. For instance, to check sample:create or sample:update permissions you will pass ['sample:create', 'sample:update'] as parameter. |
Examples
- Check
openidorprofilescope present in the token
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from axioms_drf.authentication import HasValidAccessToken
from axioms_drf.permissions import HasRequiredScopes
class APIPrivate(APIView):
authentication_classes = [HasValidAccessToken]
permission_classes = (HasAccessTokenScopes,)
access_token_scopes = ["openid", "profile"] # noqa
"""
Private API - authentication required
"""
def get(self, request):
return Response(
{"message": "All good. You are authenticated!"}, status=status.HTTP_200_OK
)
- Check
sample:rolerole present in the token
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from axioms_drf.authentication import HasValidAccessToken
from axioms_drf.permissions import HasAccessTokenRoles
class SampleRole(APIView):
"""
Sample role - create, update, read, delete
"""
authentication_classes = [HasValidAccessToken]
permission_classes = (HasAccessTokenRoles,)
access_token_roles = ["sample:role"] # noqa
def get(self, request):
return Response({"message": "Sample read."}, status=status.HTTP_200_OK,)
def post(self, request):
return Response({"message": "Sample created."}, status=status.HTTP_200_OK,)
def patch(self, request):
return Response({"message": "Sample updated."}, status=status.HTTP_200_OK,)
def delete(self, request):
return Response({"message": "Sample deleted."}, status=status.HTTP_200_OK,)
- Check permission present in the token at API method level
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from axioms_drf.authentication import HasValidAccessToken
from axioms_drf.permissions import HasAccessTokenPermissions
class SamplePermission(APIView):
"""
Sample permission applied to method level
"""
authentication_classes = [HasValidAccessToken]
permission_classes = (HasAccessTokenPermissions,)
@property
def access_token_permissions(self):
method_permissions = {
'GET': ["sample:read"] ,
'POST': ["sample:create"],
'PATCH': ["sample:update"],
'DELETE': ["sample:delete"]
}
return method_permissions[self.request.method]
def get(self, request):
return Response({"message": "Sample read."}, status=status.HTTP_200_OK,)
def post(self, request):
return Response({"message": "Sample created."}, status=status.HTTP_200_OK,)
def patch(self, request):
return Response({"message": "Sample updated."}, status=status.HTTP_200_OK,)
def delete(self, request):
return Response({"message": "Sample deleted."}, status=status.HTTP_200_OK,)
DRF Sample
To see a complete working example download DRF sample from our Github repository or simply deploy to Heroku by clicking following button. You will need to provide Axioms domain and Axioms audience to complete deployment.