Paseto authentication for Django Rest Framework
Project description
PASETO authentication for Django REST framework
Still in development, NOT READY for production.
Before using this, see https://github.com/paragonie/paseto for more information about PASETO and https://github.com/rlittlefield/pypaseto about the Python implementation.
Motivations and objectives
I needed a token authentication system for a new project and none of the available third party authentication pacakges covered my requirements completely. After some work developing my own system, I thought it would be interesting to share it and accept suggestions and contributions.
My goal is to build a token authentication system that meets the following requirements:
- Secure and simple authentication using Paseto (Platform-Agnostic SEcurity TOkens).
- Front-end agnostic (browser apps, mobile apps, etc).
- Suitable for user authentication and app integrations.
- Facilitates both reactive (blacklist tokens) and proactive (check IP, user-agent header, etc) security measures.
- Customisable token payloads, authentication conditions (transparent support for 2FA) and actions (i.e. check user login attempts).
Installation and configuration
Install using pip:
pip install django-rest-paseto-auth
Generate a 32-bytes hexadecimal secret key:
import screts
secrets.token_hex(32)
'55acd7321e85e62d0fe5ee6ea127ba4bd8ac90f6ea87f1bf2d3d5e816399d7d2'
Add it to your Django configuration and keep it as secured as the project's SECRET_KEY:
PASETO_KEY = '55acd7321e85e62d0fe5ee6ea127ba4bd8ac90f6ea87f1bf2d3d5e816399d7d2'
Add paseto_auth
to your installed applications:
INSTALLED_APPS = (
...
'paseto_auth',
)
And apply migrations:
python manage.py migrate paseto_auth
Include paseto auth URLs:
from django.urls import include, path
urlpatterns = [
path('api/auth/', include('paseto_auth.urls', namespace='paseto_auth')),
]
Finally, add the authentication scheme to the REST_FRAMEWORK
configuration or the views you want to protect:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'paseto_auth.authentication.PasetoAuthentication',
)
}
Optional configuration with default values:
PASETO_AUTH = {
'HEADER_PREFIX': 'Paseto', # Prefix for the authentication header, e.g. Bearer
'ACCESS_LIFETIME': 5*60, # Max: 10*60 seconds
'REFRESH_SHORT_LIFETIME': 12*3600, # Max: 24*3600 seconds
'REFRESH_LONG_LIFETIME': 30*24*3600, # Max: 60*24*3600 seconds
'REFRESH_PERMANENT_LIFETIME': 2*365*24*3600 # seconds
}
Usage
To get a token pair from user credentials:
$ curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "testuser", "password": "qwerty", "remember": true}' \
http://localhost:8000/api/auth/token/
----
{
'access_token': 'v2.local.wSpANWW6wNkQoVhqCWRkUp-wPfoc6fFsml7kmNlmuccDdLpqpVKmOZy6C1cYttzIt0OM-DL2uOWQKcahje0u1uSceG5mzXBZVMjDZnbXZMamF5X5JDTCZrAruVSGZ5EtliHJTFkHkgvp8c3Xmut9_8fWI09Qn6U0gaWPgM8hM_eRi7FXNHvE7ZeGOrE37SImnVZm-jCGBgMYjWzOowzQ6ZH6JvaC07eWyh6zsGQGM-l65sBlbJtTHA',
'refresh_token': 'v2.local.ZYSSnCB9Qc7FlABtXKq2Pl6uZ_Snd9P_iCBnxx18d1cYezN85fB40C_1YSr27lSVNdpeGX6usp8rEEnb3EHF5_B0sNfbG8HAoxqET0RDsVj9XSj5x8w-3jgHLzaHW-Zc6r9C_cY-wLRmMNL7obEq4ETwoYZTaLKcbxRH67GRCpQP1Rjil9ex9EGL6HKg26oJuxFG_hhlCzPYOMzgDDqUoQsl4AkdGq7fZzvZkBugXvVgY64s0TS2H10'
}
The remember
parameter will determine the refresh token short/long lifetime (see configuration section).
To get a new access token:
$ curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"refresh_token": "v2.local.ZYSSnCB9Qc7FlABtXKq2Pl6uZ_Snd9P_iCBnxx18d1cYezN85fB40C_1YSr27lSVNdpeGX6usp8rEEnb3EHF5_B0sNfbG8HAoxqET0RDsVj9XSj5x8w-3jgHLzaHW-Zc6r9C_cY-wLRmMNL7obEq4ETwoYZTaLKcbxRH67GRCpQP1Rjil9ex9EGL6HKg26oJuxFG_hhlCzPYOMzgDDqUoQsl4AkdGq7fZzvZkBugXvVgY64s0TS2H10"}' \
http://localhost:8000/api/auth/token/refresh/
----
{
'access_token': 'v2.local.wSpANWW6wNkQoVhqCWRkUp-wPfoc6fFsml7kmNlmuccDdLpqpVKmOZy6C1cYttzIt0OM-DL2uOWQKcahje0u1uSceG5mzXBZVMjDZnbXZMamF5X5JDTCZrAruVSGZ5EtliHJTFkHkgvp8c3Xmut9_8fWI09Qn6U0gaWPgM8hM_eRi7FXNHvE7ZeGOrE37SImnVZm-jCGBgMYjWzOowzQ6ZH6JvaC07eWyh6zsGQGM-l65sBlbJtTHA',
}
App tokens
You can create user-independent refresh tokens for app integrations, with a pesudo-permanent lifetime (PAESETO_AUTH['REFRESH_PERMANENT_LIFETIME']
setting) and custom Django groups/permissions. For example, to implement something like GitHub personal API tokens, you could do:
from paseto_auth.tokens import create_app_token
obj, refresh_token = create_app_token(
name="Custom application",
owner=user,
groups=groups,
perms=permissions,
)
Where owner is a generic foreign key to any object. A reversed relation could look like:
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation
class MyUserModel(models.Model):
...
api_tokens = GenericRelation('paseto_auth.AppRefreshToken')
The create_app_token
function returns the token object stored in the database and the refresh token string, that can be used to obtain access tokens an authenticate like a normal user. The authentication class will return an instance of AppIntegrationUser
that implements all the methods from the Django PermissionsMixin
.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django-rest-paseto-auth-0.1.1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | fb5ff34b230f34f597c5ab8e3fc021b67ef87d7ee84a5fcf87a31348ff2d5d70 |
|
MD5 | 58ec88f00fd8f61eff24e4b7f2c402bd |
|
BLAKE2b-256 | dc89cde40de0a03890865607062c96e0928e8d0221d8e9dabb064ea99c662e72 |
Hashes for django_rest_paseto_auth-0.1.1-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 74de0d3f01133e4a4a1d2754336fc65bac030e2cd542b7d715008a24b3d5a62d |
|
MD5 | 1defcec64c8ded24cfc34e3b13256ad2 |
|
BLAKE2b-256 | 7752a7e06ac2b1e0e2eb5af8a9c4759cae9ee784177df0e9a61d57372555adb3 |