Token Authentication module for Django Rest Framework with different token configuration for API client.

eshaan7, updated 🕥 2022-12-02 13:38:00


django-rest-durin on pypi Build Status codecov CodeFactor Language grade: Python

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:

  • Durin allows multiple tokens per user. But only one token each user per API client.
  • Each user token is associated with an API Client.
  • These API Clients are configurable via Django's Admin Interface.
  • Includes permission enforcing to allow only specific clients to make authenticated requests to certain APIViews or vice-a-versa.
  • Configure Rate-Throttling per User <-> Client pair.
  • Durin provides an option for a logged in user to remove all tokens that the server has - forcing them to re-authenticate for all API clients.
  • Durin tokens can be renewed to get a fresh expiry.
  • Durin provides a CachedTokenAuthentication backend as well which uses memoization for faster look ups.
  • Durin provides Session Management features. Refer to Session Management Views i.e.,
  • REST view for an authenticated user to get list of sessions (in context of django-rest-durin, this means AuthToken instances) and revoke a session. Useful for pages like "View active browser sessions".
  • REST view for an authenticated user to get/create/delete token against a pre-defined client. Useful for pages like "Get API key" where a user can get an API key to be able to interact directly with your project's RESTful API using cURL or a custom client.

More information can be found in the Documentation. I'd also recommend going through the example_project/ included in this repository.

Django Compatibility Matrix

PyPi versions - Python

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.

Changelog / Releases

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 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.


Add CodeQL workflow for GitHub code scanning

opened on 2022-12-02 13:37:59 by lgtm-com[bot]

Hi eshaan7/django-rest-durin!

This is a one-off automatically generated pull request from :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!


Click here to expand the FAQ section #### How often will the code scanning analysis run? By default, code scanning will trigger a scan with the CodeQL engine on the following events: * On every pull request — to flag up potential security problems for you to investigate before merging a PR. * On every push to your default branch and other protected branches — this keeps the analysis results on your repository’s *Security* tab up to date. * Once a week at a fixed time — to make sure you benefit from the latest updated security analysis even when no code was committed or PRs were opened. #### What will this cost? Nothing! The CodeQL engine will run inside GitHub Actions, making use of your [unlimited free compute minutes for public repositories]( #### What types of problems does CodeQL find? The CodeQL engine that powers GitHub code scanning is the exact same engine that powers The exact set of rules has been tweaked slightly, but you should see almost exactly the same types of alerts as you were used to on we’ve enabled the [`security-and-quality` query suite]( for you. #### How do I upgrade my CodeQL engine? No need! New versions of the CodeQL analysis are constantly deployed on; your repository will automatically benefit from the most recently released version. #### The analysis doesn’t seem to be working If you get an error in GitHub Actions that indicates that CodeQL wasn’t able to analyze your code, please [follow the instructions here]( to debug the analysis. #### How do I disable If you have LGTM’s automatic pull request analysis enabled, then you can [follow these steps to disable the LGTM pull request analysis]( You don’t actually need to remove your repository from; it will automatically be removed in the next few months as part of the deprecation of ([more info here]( #### Which source code hosting platforms does code scanning support? GitHub code scanning is deeply integrated within GitHub itself. If you’d like to scan source code that is hosted elsewhere, we suggest that you create a mirror of that code on GitHub. #### How do I know this PR is legitimate? This PR is filed by the official GitHub App, in line with the [deprecation timeline that was announced on the official GitHub Blog]( The proposed GitHub Action workflow uses the [official open source GitHub CodeQL Action]( If you have any other questions or concerns, please join the discussion [here]( in the official GitHub community! #### I have another question / how do I get in touch? Please join the discussion [here]( to ask further questions and send us suggestions!

Fix: migrations being generated when settings are altered

opened on 2022-11-25 18:51:33 by Caiofcas


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:


from datetime import timedelta

DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

REST_DURIN = { "DEFAULT_TOKEN_TTL": timedelta(hours=6), } ```


Generated by Django 3.2.11 on 2022-11-25 18:02

import datetime from django.db import migrations, models

class Migration(migrations.Migration):

dependencies = [
    ('durin', '0002_client_throttlerate'),

operations = [
        field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
        field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
        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)'),


AuthTokenAdmin list_filter is causing performance problems (mostly timeouts)

opened on 2022-06-17 04:09:02 by sunweiyang

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?

Setup/usage with Social Auth

opened on 2021-10-06 00:39:03 by daniel-skale

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.

AuthTokenManager.get_or_create calls wrong create

opened on 2021-06-06 13:57:28 by hodunov

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)

Ability to store metadata/settings as part of Client <-> User relationship

opened on 2021-04-28 08:35:43 by eshaan7

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.


v1.1.0 2022-10-31 18:13:03


v1.0.0 (Session Management Featues) 2022-01-20 12:43:55


v0.4.0 (Python 3.10, Django 4.0) 2022-01-20 11:21:06


AUTHTOKEN_SELECT_RELATED_LIST | Fix permissions classes 2021-05-19 12:45:45


UserClientRateThrottling | various other improvments and fixes. 2021-05-19 10:13:50


v0.1.0 (Initial Release) 2020-10-25 15:38:30


Eshaan Bansal

Work @eshaan-deepsource. Maintainer @intelowlproject under @honeynet (GSoC'20,21,22).

GitHub Repository Homepage

django drf drf-tokens tokenauthentication api-client django-rest-framework python hacktoberfest