django-rest-knox Documentation

repository·develop·Indexed 22 days ago

https://github.com/jazzband/django-rest-knox

A token-based authentication module for Django REST Framework (DRF) that enhances security and flexibility over DRF's default implementation. Key features include support for multiple tokens per user for multi-device login, secure hashed token storage to protect against database compromises, and configurable token expiration (TOKEN_TTL) with optional auto-refresh behavior.

Tokens
4.8K
Snippets
15
Records
25
Agent score
79%

What's inside django-rest-knox

  1. What is django-rest-knox?

    develop

    django-rest-knox is an authentication module for Django REST Framework (DRF) that provides token-based authentication. It improves upon DRF's built-in TokenAuthentication in three key ways:

    1. Multiple Tokens per User: Unlike DRF, which limits users to one token, Knox allows each device/client to have its own unique token. This enables individual device logout and the ability to revoke all tokens for a user simultaneously.
    2. Secure Token Storage: Knox stores tokens as secure hashes (similar to passwords) rather than unencrypted strings. This protects accounts even if the database is compromised.
    3. Token Expiration: Knox supports configurable token expiration, whereas DRF tokens do not have an inbuilt expiration mechanism. By default, tokens expire after 10 hours.
  2. What is Django-Rest-Knox and how does it differ from DRF TokenAuthentication?

    develop

    Django-Rest-Knox is a token-based authentication library for Django REST Framework (DRF). It improves upon DRF's built-in TokenAuthentication in three key areas:

    1. Multi-device support: Unlike DRF, which is limited to one token per user, Knox provides a unique token for every login call. This allows multiple devices to be logged in simultaneously and enables individual device logout without affecting others. It also includes settings to limit the total number of tokens per user.
    2. Security (Encryption): DRF tokens are stored unencrypted in the database. Knox tokens are stored in an encrypted form, protecting user accounts even if the database is compromised.
    3. Token Expiration: While DRF tokens do not expire by default, Knox allows you to configure a token expiry time in your application settings (the default is 10 hours).
  3. Configure django-rest-knox settings

    develop

    All Knox settings are namespaced within the REST_KNOX dictionary in your Django settings.py. You can also use top-level variables like KNOX_TOKEN_MODEL for specific swappable dependencies. Use the REST_KNOX dictionary to override default behaviors such as token lifetime, hashing algorithms, and refresh logic.

    from datetime import timedelta
    from rest_framework.settings import api_settings
    
    # Top-level variable for swappable dependency
    KNOX_TOKEN_MODEL = 'knox.AuthToken'
    
    REST_KNOX = {
      'SECURE_HASH_ALGORITHM': 'hashlib.sha512',
      'AUTH_TOKEN_CHARACTER_LENGTH': 64,
      'TOKEN_TTL': timedelta(hours=10),
      'USER_SERIALIZER': 'knox.serializers.UserSerializer',
      'TOKEN_LIMIT_PER_USER': None,
      'AUTO_REFRESH': False,
      'AUTO_REFRESH_MAX_TTL': None,
      'MIN_REFRESH_INTERVAL': 60,
      'AUTH_HEADER_PREFIX': 'Token',
      'EXPIRY_DATETIME_FORMAT': api_settings.DATETIME_FORMAT,
      'TOKEN_MODEL': 'knox.AuthToken',
    }
  4. Configure global TokenAuthentication and handle LoginView

    develop

    You can enable TokenAuthentication globally for all views by adding it to REST_FRAMEWORK["DEFAULT_AUTHENTICATION_CLASSES"] in your Django settings.

    Warning: If TokenAuthentication is your only default authentication class, you must overwrite the Knox LoginView. Otherwise, the login view will require a token to generate a new token, making it impossible to log in.

    To allow users to log in using other methods (like BasicAuthentication), overwrite knox.views.LoginView and set the appropriate authentication_classes.

    # views.py
    from knox.views import LoginView as KnoxLoginView
    from rest_framework.authentication import BasicAuthentication
    
    class LoginView(KnoxLoginView):
        authentication_classes = [BasicAuthentication]
    # urls.py
    from knox import views as knox_views
    from yourapp.api.views import LoginView
    
    urlpatterns = [
         path(r'login/', LoginView.as_view(), name='knox_login'),
         path(r'logout/', knox_views.LogoutView.as_view(), name='knox_logout'),
         path(r'logoutall/', knox_views.LogoutAllView.as_view(), name='knox_logoutall'),
    ]
  5. Work on the documentation with Mkdocs

    develop

    The project documentation is generated using Mkdocs. You can run the documentation locally using the provided mkdocs.sh script, which runs Mkdocs inside a Docker container.

    Running the documentation server

    Running the script without parameters triggers the serve command, exposing the documentation on localhost:8000.

    To change the port, set the MKDOCS_DEV_PORT environment variable.

    Passing Mkdocs commands

    You can pass standard mkdocs commands directly to the script (e.g., build or --help).

  6. Configure django-rest-knox in Django settings

    develop

    To set up Knox in your Django project, follow these steps:

    1. Update INSTALLED_APPS: Add 'rest_framework' and 'knox' to your INSTALLED_APPS. If you were previously using rest_framework.authtoken, remove it.
    2. Set Default Authentication: Configure Django Rest Framework to use Knox's TokenAuthentication as the default authentication class.
    3. Add URL Patterns: Include the Knox URL patterns in your project's urls.py.
    4. Run Migrations: Apply the database migrations for the Knox models.
    # INSTALLED_APPS configuration
    INSTALLED_APPS = (
      ...
      'rest_framework',
      'knox',
      ...
    )
    
    # REST_FRAMEWORK configuration
    REST_FRAMEWORK = {
        'DEFAULT_AUTHENTICATION_CLASSES': ('knox.auth.TokenAuthentication',),
        ...
    }
  7. Run the tests locally

    develop

    To run the test suite across all supported Python and Django versions using Docker, execute the provided shell script. This is useful for debugging tests locally without manually managing multiple environments.

    Alternatively, you can run tox in the root folder, though managing the version matrix is more manual.

    ./docker-run-tests.sh
  8. Include Knox URLs in your Django project

    develop

    Knox provides a pre-configured URL pattern containing its three default views. To include them in your project, add include('knox.urls') to your urlpatterns.

    CRITICAL: You must use the string syntax (e.g., 'knox.urls') rather than importing the module directly. Importing knox.urls will cause an import-time failure because the module references the User model.

    urlpatterns = [
      #...snip...
      path(r'api/auth/', include('knox.urls'))
      #...snip...
    ]
  9. Use TokenAuthentication for API views

    develop

    Knox provides TokenAuthentication to integrate with Django REST Framework's authentication system. To protect an APIView or ViewSet, add TokenAuthentication to the authentication_classes attribute.

    To authenticate requests, include an Authorization header with the value Token <your_token_string>. Tokens are generated via Knox's provided views (e.g., LoginView).

    from rest_framework.permissions import IsAuthenticated
    from rest_framework.response import Response
    from rest_framework.views import APIView
    
    from knox.auth import TokenAuthentication
    
    class ExampleView(APIView):
        authentication_classes = (TokenAuthentication,)
        permission_classes = (IsAuthenticated,)
    
        def get(self, request, format=None):
            content = {
                'foo': 'bar'
            }
            return Response(content)