Package: django-pat
Django PAT (Personal Access Tokens)This application creates personal access tokens that clients can send via HTTP headers to authenticate as a particular user.
This application expands on the standard functionality provided in REST Framework tokens by allowing users to create
more than one token and cycle/revoke tokens for security purposes.Personal access tokens are API keys that allow clients to pass a secure value to an API without having to first exchange
a username and password. This  makes interactions between machines straightforward and consistent. While these tokens are
easy to use, it is important to ensure they are secure. This application accomplishes this security by:Hashing all token values after creation. This ensures admins of the application and malicious actors are never be able
to access token values in plain text via a data breach.Allowing for tokens to be "cycled". This is accomplished by revoking existing tokens and creating new ones. Clients
can do this easily via APIs on a regular basis or as needed, if they believe a token has been compromised.UsageBy default, both the standard middleware and the REST Framework authentication will look for the token in theAuthorizationHTTP header with a prefix ofAccess-Token. So this might look likeAuthorization: Access-Token 41ecea63-66eb-4e6a-bffd-e85cd29718abInitial SetupInstall the package:pip install django-patAdddjango_patto theINSTALLED_APPSof your projectAdd thePAT_SECRETvalue to your settings file to hash secrets. This value should be kept secret!PAT_SECRET="super-secret-hashing-key"Django MiddlewareAdd the middleware to your middleware stackMIDDLEWARE=["django.contrib.auth.middleware.AuthenticationMiddleware","django_pat.middleware.PatAuthenticationMiddleware",]REST FrameworkAdd the authentication class to your DRF default authentication classesREST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":["django_pat.rest_framework.auth.PatAuthentication","rest_framework.authentication.SessionAuthentication",],}Optional: Add Personal Access Token ViewsAPIs can be added to your Django application to create, retrieve, and revoke tokens out of the box. This will create new Django Rest Routes at/personalAccessTokens# urls.pyfromdjango.urlsimportincludefromdjango.urlsimportpathfromdjango_pat.rest_framework.urlsimportrouteraspat_routerurlpatterns=[# other routes...path("api/",include(pat_router.urls)),]Alternatively, thePersonalAccessTokenViewSetcan be added to any route you prefer.ConfigurationAlong with thePAT_SECRETvalue that is required, you can also configure certain behaviors of the package in your Django
application settings.PAT_CUSTOM_HEADER- Sets the HTTP header to check for the token. This defaults toAuthorizationPAT_CUSTOM_HEADER_PREFIX- Sets the prefix for the header value. This defaults toAccess-Token. The middleware
and the REST authentication expect a space between the prefix and the token value.PAT_USES_SHARED_HEADER- If set to True, then the package will not attempt to validate the prefix on the authorization
header. This is most useful when different prefixes are used for different types of authentication, but are all sent
using the same HTTP header.Implementation DetailsAccess token values are implemented as UUID4 values. These are sufficiently unique to remain secure and avoid collisions.Security ConcernsPersonal access token records should NOT be deleted from the database, even if revoked.If tokens are deleted, there is the
possibility that the token value could be reassigned to a different user at a later time. If the user originally provided
the token retains it, they may later use it to inadvertently access the API as the new user. The default behavior of this
application in the admin is torevoketoken instead of deleting them, and it is recommended users follow this same
pattern.If a brute force attack is a concern, then rate limiting should be applied to API views. The possibility of brute
forcing all possible UUID4 values is unlikely, but rate limiting provides another way to avoid it.Alternative PackagesDjango REST Framework API KeyThis project
similarly provides the ability to create and manage API keys for machine-to-machine API calls. It is focused on
supporting unauthorized requests, i.e. those not linked to a particular user. There are a few reasons I chose to go
with a different option.The Django REST Framework API Keys is tightly coupled with Django REST Framework. I wanted this package to support
DRF without being coupled to it, such that developers who want to build APIs without DRF have the option.The default behavior of Django REST Framework API Keys is not linked to users. The key can be extended to have a
reference to the user, but this requires additional configuration and the default model table is still created for
the base API key model. This means that by default developers will be able to use existing user permissions with
working with a User API Key. See:Issue 180The Django REST Framework API Key encryption technique used by the application creates a slower API. This has been
alleviated in Django User API Key by using HMAC hashing instead. See:Issue 173The primary key pattern of the Django REST Framework API Key records use special characters, making them difficult
to encode for browsers. See:Issue 128Django REST Framework TokenAuthenticationThe standard DRFTokenAuthenticationmodel has a couple of drawbacks that this project attempts to avoid by
expanding on the pattern. In the standard token pattern:The token value is stored in a plain-text formatThe token value acts as the primary key of the token. If building an API to retrieve the token, you would not
want to use this key in a URL, as it would go over the network in plain-text.Each user can only have a single token.Revoking one user's token opens up the possibility of generating the same token again for a different user.