Per API client token authentication Module for Django REST Framework.
The idea is to provide one library that does token auth for multiple Web/CLI/Mobile API clients (i.e. devices/user-agents) via one interface but allows different token configuration for each client.
Durin authentication is token based, similar to the TokenAuthentication
built in to DRF. However, it adds some extra sauce:
APIViews
or vice-a-versa.CachedTokenAuthentication
backend as well which uses memoization for faster look ups.AuthToken
instances) and revoke a session. Useful for pages like "View active browser sessions".More information can be found in the Documentation. I'd also recommend going through the example_project/
included in this repository.
If your project uses an older verison of Django or Django Rest Framework, you can choose an older version of this project.
| This Project | Python Version | Django Version | Django Rest Framework | | ------------ | -------------- | ----------------------- | --------------------- | | 0.1+ | 3.5 - 3.10 | 2.2, 3.0, 3.1, 3.2, 4.0 | 3.7>= |
Make sure to use at least DRF 3.10
when using Django 3.0
or newer.
All releases should be listed in the releases tab on GitHub.
See CHANGELOG for a more detailed listing.
This project is published with the MIT License. See https://choosealicense.com/licenses/mit/ for more information about what this means.
Durin is inpired by the django-rest-knox and django-rest-multitokenauth libraries and adopts some learnings and code from both.
Hi eshaan7/django-rest-durin
!
This is a one-off automatically generated pull request from LGTM.com :robot:. You might have heard that we’ve integrated LGTM’s underlying CodeQL analysis engine natively into GitHub. The result is GitHub code scanning!
With LGTM fully integrated into code scanning, we are focused on improving CodeQL within the native GitHub code scanning experience. In order to take advantage of current and future improvements to our analysis capabilities, we suggest you enable code scanning on your repository. Please take a look at our blog post for more information.
This pull request enables code scanning by adding an auto-generated codeql.yml
workflow file for GitHub Actions to your repository — take a look! We tested it before opening this pull request, so all should be working :heavy_check_mark:. In fact, you might already have seen some alerts appear on this pull request!
Where needed and if possible, we’ve adjusted the configuration to the needs of your particular repository. But of course, you should feel free to tweak it further! Check this page for detailed documentation.
Questions? Check out the FAQ below!
Versions:
sh
$ pip freeze
...
Django==3.2.11
djangorestframework==3.13.1
django-rest-durin==1.1.0
...
There are two settings changes which can generate new migrations inside the installed durin files currently.
The first one is when you change the DEFAULT_AUTO_FIELD
setting in django to something other than models.BigAutoField
, it can be detected by django as a change in the durin provided models, which can lead to migrations being generated for durin models.
This happens since durin does not explicitly provide an AppConfig
class with the default_auto_field
property set. See this SO question for another explanation of the problem.
The second is when you change one of the values which is directly referenced in one of the fields default
argument (Client.token_ttl
field with DEFAULT_TOKEN_TTL
). If you change the value of these settings, it's interpreted as a change in the value of the argument, and it generates a migration.
This one can be fixed by changing the arg to reference a function which reads the setting at run time.
Example migration generated inside the durin migrations
directory when you change some of this settings:
settings.py
:
```python
from datetime import timedelta
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
REST_DURIN = { "DEFAULT_TOKEN_TTL": timedelta(hours=6), } ```
```python
import datetime from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('durin', '0002_client_throttlerate'),
]
operations = [
migrations.AlterField(
model_name='authtoken',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='client',
name='id',
field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='client',
name='token_ttl',
field=models.DurationField(default=datetime.timedelta(seconds=21600), help_text='\n Token Time To Live (TTL) in timedelta. Format: <code>DAYS HH:MM:SS</code>.\n ', verbose_name='Token Time To Live (TTL)'),
),
]
```
Our app has ~50k User objects and even more Client objects, and currently, because of AuthTokenAdmin's list_filter, our app times out every time we access the AuthToken list page in Django admin (because the filter lists every single one of these User and Client objects as possible filters). Can AuthTokenAdmin's list_filter be removed?
Hi, was wondering if there are any additional setup required when authenticating a Google OAuth token? The header format is of the form Authorization: Token some_hash
, but for some reason the response form calling an API afterwards returns {detail: Invalid token. }
. Can this be caused if a default expiry and additional settings are not set? When not using 3rd party Oauth, the client logs in and is able to perform API calls with the token created by durin.
Hi!
Thanks for the library, it really helped me solve my problem. But while implementing authorization via GraphQL I encountered the following problem:AuthToken.objects.get_or_create(user=user, client=auth_client)
method does not work correctly.
Expected behavior: classic get_or_create
Real result: error NOT NULL constraint failed: durin_authtoken.expiry
A piece of code in which an error occurs:
login(request, user)
token, created = AuthToken.objects.get_or_create(user=user, client=auth_client)
If I wrap it in try-exept, everything works as it should.
try:
token = AuthToken.objects.get(user=user, client=auth_client)
except AuthToken.DoesNotExist:
token = AuthToken.objects.create(user=user, client=auth_client)
There can be use cases where developers wish to store settings/metadata about a user specific to a client. (For example, theme name, styling, avatar, display name, etc.)
Few initial implementation ideas:
- Provide an abstract UserClient
model with user_id
and client_id
fields that developers could subclass.
- Provide an UserClientSettings
model with user_id
, client_id
, metadata = JsonField
fields that developers can directly use.
Model should provide a shortcut method:
python3
def get_current(request: "rest_framework.request.Request") -> UserClient
More ideas welcome.
See CHANGELOG.
See CHANGELOG.
See CHANGELOG.
See CHANGELOG.
See CHANGELOG.
See CHANGELOG.
Work @eshaan-deepsource. Maintainer @intelowlproject under @honeynet (GSoC'20,21,22).
GitHub Repository Homepagedjango drf drf-tokens tokenauthentication api-client django-rest-framework python hacktoberfest