Authentication Module for django rest auth

Overview

django-rest-knox

image

Authentication Module for django rest auth

Knox provides easy to use authentication for Django REST Framework The aim is to allow for common patterns in applications that are REST based, with little extra effort; and to ensure that connections remain secure.

Knox authentication is token based, similar to the TokenAuthentication built in to DRF. However, it overcomes some problems present in the default implementation:

  • DRF tokens are limited to one per user. This does not facilitate securely signing in from multiple devices, as the token is shared. It also requires all devices to be logged out if a server-side logout is required (i.e. the token is deleted).

    Knox provides one token per call to the login view - allowing each client to have its own token which is deleted on the server side when the client logs out.

    Knox also provides an option for a logged in client to remove all tokens that the server has - forcing all clients to re-authenticate.

  • DRF tokens are stored unencrypted in the database. This would allow an attacker unrestricted access to an account with a token if the database were compromised.

    Knox tokens are only stored in a secure hash form (like a password). Even if the database were somehow stolen, an attacker would not be able to log in with the stolen credentials.

  • DRF tokens track their creation time, but have no inbuilt mechanism for tokens expiring. Knox tokens can have an expiry configured in the app settings (default is 10 hours.)

More information can be found in the Documentation

Run the tests locally

If you need to debug a test locally and if you have docker installed:

simply run the ./docker-run-tests.sh script and it will run the test suite in every Python / Django versions.

You could also simply run regular tox in the root folder as well, but that would make testing the matrix of Python / Django versions a bit more tricky.

Work on the documentation

Our documentation is generated by Mkdocs.

You can refer to their documentation on how to install it locally.

Another option is to use mkdocs.sh in this repository. It will run mkdocs in a docker container.

Running the script without any params triggers the serve command. The server is exposed on localhost on port 8000.

To configure the port the serve command will be exposing the server to, you can use the following env var:

MKDOCS_DEV_PORT="8080"

You can also pass any mkdocs command like this:

./mkdocs build
./mkdocs --help

Check the Mkdocs documentation for more.

Comments
  • Latest release 3.3.1 fails to deploy to pypi

    Latest release 3.3.1 fails to deploy to pypi

    see job log: https://travis-ci.org/James1345/django-rest-knox/jobs/409780228

    HTTPError: 400 Client Error: User 'xxx.xxx' does not have a verified primary email address. Please add a verified primary email before attempting to upload to PyPI. See https://pypi.org/help/#verified-email for more information.for more information. for url: https://upload.pypi.org/legacy/

    Original author was informed by me.

    Blocker 
    opened by belugame 37
  • create a release for django 4.0 compare

    create a release for django 4.0 compare

    In auth.py

    from django.utils.translation import ugettext_lazy as _ no longer works as ugettext_lazy is removed.

    develop branch seems to have solved this issue.

    Can a release be created?

    opened by tr-conway 23
  • Encrypted tokens

    Encrypted tokens

    Adds a encrypted field/column and support for encrypting the token with a passphrase. It also includes a tokens endpoint as well as hook into password change and reset as appropriate.

    The idea is to support user's retrieving/managing their tokens in such a way that someone in possession of the DB still couldn't retrieve the tokens. Useful on a "API key management" screen that requires the user confirm that they are the logged in user by providing their login credentials for every token operation.

    opened by rpatterson 23
  • How does it work?

    How does it work?

    Can someone provide a short example or tutorial to explain how knox works? I have a DRF backend app and many client (web, ios, android). I would like to add some imprivment to my backend to allow the user to have a different token by client. But when I try to login trough api/auth/login/ endpoint, I got a error 401. When I look at the code, the LoginView need the user to be logged in. How is it possible to be logged in in the LoginView (that doesn't makes sens for me ^^)?

    Thank you for your help!

    question 
    opened by BenDevelopment 18
  • [DONT MERGE] feature: add json authentication view

    [DONT MERGE] feature: add json authentication view

    First off, I am not sure why this doesnt already exist, maybe it was intentional but anyway here it is. This is allows a json request with username and password to be sent to an endpoint instead of using Basic HTTP Authentication.

    For now this is simply disabled by default, ive added some tests but I reckon more is required since it aims to authenticate a user -- even though it relies on the authenticate() from django to do it.

    • [ ] This PR does not incorporate another PRs Ive sent just yet, because they are still pending an answer: https://github.com/James1345/django-rest-knox/pull/109
    • [ ] docs are not updated yet
    opened by sphrak 17
  • Performance Issue

    Performance Issue

    As the readme doesn't really state it: django-rest-knox has a major performance issue.

    https://github.com/James1345/django-rest-knox/blob/master/knox/auth.py#L50

    This line leads to major performance hits once one reaches significant user numbers, as each API request leads to all tokens being sent do the Django instances. Once reaching a few tens of thousands of users and more than a handful of requests per second, the application is spending more time receiving/parsing SQL and guessing tokens than doing some actual work.

    One way to change this would be the following: Split the token in 2 parts:

    • Part one is an identifier for a database column, e.g. a random string
    • Part two is the very token knox currently uses

    This would lead to only querying for a single row (the one matching part on), then comparing one hash.

    Funfact: While loadtesting I watched my servers handle > 100mbit/s of SQL due to this bug.

    opened by timbuchwaldt 17
  • add: optional token limit per user object

    add: optional token limit per user object

    @belugame This is what I got thus far. I have verified the functionality manually -- it works but I am having trouble with the test not respecting the overridden TOKEN_LIMIT, thus the test fails -- I figured the default settings value should be None since this option does come with a performance cost and is not needed by everyone.

    I mean I could just set knox_settings.TOKEN_LIMIT = 10 inside the testcase but.. is that the correct way?

    Related: https://github.com/James1345/django-rest-knox/issues/108

    enhancement 
    opened by sphrak 16
  • feat: add token prefix option

    feat: add token prefix option

    Hi @belugame, @James1345

    Thanks for creating django-rest-knox!

    This feature will add an optional token prefix to the library that can be used to detect these tokens easily and quickly revoke them in case they are leaked. The same mechanism is also used by GitHub and GitLab. See also the issue: https://github.com/James1345/django-rest-knox/issues/271

    This is just a MR to see, if you would accept that feature. I will provide tests and documentation, once you approve.

    Fixes https://github.com/James1345/django-rest-knox/issues/271

    @dlouzan @bufferoverflow @fh1ch @nejch

    opened by max-wittig 13
  • Recommended method of refreshing tokens

    Recommended method of refreshing tokens

    I would like to implement a method of refreshing tokens from a single page app. The refresh itself seems pretty simple, but I was wondering what the best way of accessing a token's expiration time is. I was thinking about overriding the login view to return the expiration time as well, but the manager method to create new tokens only returns the token's key. Any input would be much appreciated.

    enhancement help wanted 
    opened by cdriehuys 13
  • Performance improvements part II

    Performance improvements part II

    This is the second part, with a newer version. Prevents a break with existing installations. Unfortunately, this contains the commit of the other fork.

    opened by jasjukaitis 11
  • Allowed usage of custom AuthToken based on knox.AbstractAuthToken

    Allowed usage of custom AuthToken based on knox.AbstractAuthToken

    Hi guys, I really love this package and I regularly use it in projects that require token authentication. I recently came across a situation in which I needed to support multiple profiles for the user in a multi-platform project. So, it is required to link the token with both the user profile and the platform client. Hence, I came up with this solution and I hope that it would be of good use to the package users. Please, inform me if there is any unclear change and point out any change that needs further modifications. Thanks.

    opened by Khalidm98 10
  • Update gh actions; Add Django 4.1, Python 3.11

    Update gh actions; Add Django 4.1, Python 3.11

    Add

    • Django 4.1 has been released! https://docs.djangoproject.com/en/4.1/releases/4.1/
    • Python 3.11 has been released!

    Update

    • GitHub Actions: Deprecating save-state and set-output commands https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
    • Bump GH Actions versions
    opened by Rotzbua 0
  • OpenAPI schema generation

    OpenAPI schema generation

    What is the recommended way to automatically generate an OpenAPI schema of the knox API endpoints? Neither the in the Django REST framework integrated schema builder (python manage.py generateschema) nor drf-spectacular seem to work out of the box.

    Django==4.1.4 
    psycopg2-binary==2.9.5
    djangorestframework==3.14.0
    django-cors-headers==3.13.0
    django-rest-knox==4.2.0
    cryptography==38.0.4
    markdown==3.4.1
    django-filter==22.1
    pyyaml==6.0
    uritemplate==4.1.1
    coreapi==2.3.3
    drf-spectacular==0.25.1 
    

    generateschema:

      /api/login/:
        post:
          operationId: createLogin
          description: ''
          parameters: []
          requestBody:
            content:
              application/json:
                schema: {}
              application/x-www-form-urlencoded:
                schema: {}
              multipart/form-data:
                schema: {}
          responses:
            '201':
              content:
                application/json:
                  schema: {}
              description: ''
          tags:
          - api
      /api/logout/:
        post:
          operationId: createLogout
          description: ''
          parameters: []
          requestBody:
            content:
              application/json:
                schema: {}
              application/x-www-form-urlencoded:
                schema: {}
              multipart/form-data:
                schema: {}
          responses:
            '201':
              content:
                application/json:
                  schema: {}
              description: ''
          tags:
          - api
      /api/logoutall/:
        post:
          operationId: createLogoutAll
          description: 'Log the user out of all sessions
    
            I.E. deletes all auth tokens for the user'
          parameters: []
          requestBody:
            content:
              application/json:
                schema: {}
              application/x-www-form-urlencoded:
                schema: {}
              multipart/form-data:
                schema: {}
          responses:
            '201':
              content:
                application/json:
                  schema: {}
              description: ''
          tags:
          - api
    

    spectacular

    /home/worker/django/api/views.py:8: Error [LoginView]: unable to guess serializer. This is graceful fallback handling for APIViews. Consider using GenericAPIView as view base class, if view is under your control. Either way you may want to add a serializer_class (or method). Ignoring view for now.
    /home/worker/django/api/views.py:8: Warning [LoginView]: could not resolve authenticator <class 'knox.auth.TokenAuthentication'>. There was no OpenApiAuthenticationExtension registered for that class. Try creating one by subclassing it. Ignoring for now.
    /usr/local/lib/python3.11/site-packages/knox/views.py:70: Error [LogoutView]: unable to guess serializer. This is graceful fallback handling for APIViews. Consider using GenericAPIView as view base class, if view is under your control. Either way you may want to add a serializer_class (or method). Ignoring view for now.
    /usr/local/lib/python3.11/site-packages/knox/views.py:70: Warning [LogoutView]: could not resolve authenticator <class 'knox.auth.TokenAuthentication'>. There was no OpenApiAuthenticationExtension registered for that class. Try creating one by subclassing it. Ignoring for now.
    /usr/local/lib/python3.11/site-packages/knox/views.py:81: Error [LogoutAllView]: unable to guess serializer. This is graceful fallback handling for APIViews. Consider using GenericAPIView as view base class, if view is under your control. Either way you may want to add a serializer_class (or method). Ignoring view for now.
    /usr/local/lib/python3.11/site-packages/knox/views.py:81: Warning [LogoutAllView]: could not resolve authenticator <class 'knox.auth.TokenAuthentication'>. There was no OpenApiAuthenticationExtension registered for that class. Try creating one by subclassing it. Ignoring for now.
    
    ...
    
      /api/login/:
        post:
          operationId: api_login_create
          tags:
          - api
          security:
          - {}
          responses:
            '200':
              description: No response body
      /api/logout/:
        post:
          operationId: api_logout_create
          tags:
          - api
          responses:
            '200':
              description: No response body
      /api/logoutall/:
        post:
          operationId: api_logoutall_create
          description: |-
            Log the user out of all sessions
            I.E. deletes all auth tokens for the user
          tags:
          - api
          responses:
            '200':
              description: No response body
    
    
    
    opened by rbuffat 0
  • AUTO_REFRESH method never worked

    AUTO_REFRESH method never worked

    Hello Know Team,

    I tried this module, and its looks amazing, but I just noticed one thing on this app. its regarding the Auto Refresh method.

    if auth_token.expiry is not None: if auth_token.expiry < timezone.now(): username = auth_token.user.get_username() auth_token.delete() token_expired.send(sender=self.__class__, username=username, source="auth_token") return True

    above code line auto delete token if already expired even AUTO_REFRESH = True

    opened by laksithakumara-cb 3
  • PR(#272) Replaces code for PR (#275)

    PR(#272) Replaces code for PR (#275)

    As stated in the title, the PR that was most recently merged into the develop branch (#272) that adds the option for token prefixes undoes some of the work done in PR #275. Namely in the model.py file, the AuthTokenManager class lost it's **kwargs parameters so that you can't really populate any custom values to the AuthToken custom class you create...

    opened by brukberhane 0
Releases(4.2.0)
  • 4.2.0(Jan 31, 2022)

    • compatibility with Python up to 3.10 and Django up to 4.0
    • integration with github CI instead of travis
    • Migration: "salt" field of model "AuthToken" is removed
    Source code(tar.gz)
    Source code(zip)
  • 4.1.0(Jun 1, 2019)

    • Expiry format now defaults to whatever is used Django REST framework
    • The behavior can be overriden via EXPIRY_DATETIME_FORMAT setting
    • Fully customizable expiry format via format_expiry_datetime
    • Fully customizable response payload via get_post_response_data
    Source code(tar.gz)
    Source code(zip)
  • 4.0.1(Apr 10, 2019)

  • 4.0.0(Mar 27, 2019)

    BREAKING This is a major release version because it breaks the existing API. Changes have been made to the create() method on the AuthToken model. It now returns the model instance and the raw token instead of just the token to allow the expiry field to be included in the success response.

    Model field of AuthToken has been renamed from expires to expiry to remain consistent across the code base.

    This patch requires you to run a migration and depending on your usage you might also have to adjust your code.

    Source code(tar.gz)
    Source code(zip)
  • 3.6.0(Dec 31, 2018)

  • 3.5.0(Dec 21, 2018)

  • 3.4.0(Nov 12, 2018)

    Our release cycle was broken since 3.1.5, hence you can not find the previous releases on pypi. We now fixed the problem.

    • #129, #128 fixed
    • Adds optional token amount limit per user
    • Changelog and Readme converted to markdown
    • Auth header prefix is now configurable
    • We ensure not to have flake8 errors in our code during our build
    • MIN_REFRESH_INTERVAL is now a configurable setting
    Source code(tar.gz)
    Source code(zip)
  • 3.3.1(Sep 28, 2018)

    We skipped to release 3.2.0, 3.2.1 and 3.3.0 as we had problems publishing them to pypi.

    3.3.1 has:

    • Django 2.1 and Python 3.7 compability
    • Signal "token_expired" gets emitted when old tokens are deleted

    Refer to changelog for more info about the skipped releases.

    Source code(tar.gz)
    Source code(zip)
  • 3.2.1(Aug 19, 2018)

  • 3.2.0(Jul 31, 2018)

    Introduce new setting AUTO_REFRESH for controlling if token expiry time should be extended automatically on requests within the current expiry period.

    Source code(tar.gz)
    Source code(zip)
  • 3.1.5(Jul 13, 2018)

  • 3.1.4(Apr 9, 2018)

  • 3.1.3(Feb 26, 2018)

  • 3.1.2(Jan 28, 2018)

  • 3.1.1(Jan 25, 2018)

  • 3.1.0(Dec 18, 2017)

  • 3.0.3(Sep 21, 2017)

  • 3.0.2(Jun 23, 2017)

  • 3.0.1(Apr 24, 2017)

  • 3.0(Feb 26, 2017)

    Please be aware: updating to this version requires applying a database migration. All clients will need to reauthenticate.

    • Big performance fix: Introduction of token_key field to avoid having to compare a login request's token against each and every token in the database (issue #21)
    • increased test coverage
    Source code(tar.gz)
    Source code(zip)
  • 2.2.2(Dec 29, 2016)

  • 2.2.1(Dec 16, 2016)

    v. 2.2.1

    Please be aware: updating to his version requires applying a database migration

    • Introducing token_key to avoid loop over all tokens on login-requests
    • Signals are sent on login/logout
    • Test for invalid token length
    • Cleanup in code and documentation
    Source code(tar.gz)
    Source code(zip)
Owner
James McMahon
James McMahon
Authentication for Django Rest Framework

Dj-Rest-Auth Drop-in API endpoints for handling authentication securely in Django Rest Framework. Works especially well with SPAs (e.g React, Vue, Ang

Michael 1.1k Dec 28, 2022
REST implementation of Django authentication system.

djoser REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such

Sunscrapers 2.2k Jan 1, 2023
A JSON Web Token authentication plugin for the Django REST Framework.

Simple JWT Abstract Simple JWT is a JSON Web Token authentication plugin for the Django REST Framework. For full documentation, visit django-rest-fram

Jazzband 3.3k Jan 4, 2023
Country-specific Django helpers, to use in Django Rest Framework

django-rest-localflavor Country-specific serializers fields, to Django Rest Framework Documentation (soon) The full documentation is at https://django

Gilson Filho 19 Aug 30, 2022
RESTler is the first stateful REST API fuzzing tool for automatically testing cloud services through their REST APIs and finding security and reliability bugs in these services.

RESTler is the first stateful REST API fuzzing tool for automatically testing cloud services through their REST APIs and finding security and reliability bugs in these services.

Microsoft 1.8k Jan 4, 2023
Mlflow-rest-client - Python client for MLflow REST API

Python Client for MLflow Python client for MLflow REST API. Features: Minimal de

MTS 35 Dec 23, 2022
Automated generation of real Swagger/OpenAPI 2.0 schemas from Django REST Framework code.

drf-yasg - Yet another Swagger generator Generate real Swagger/OpenAPI 2.0 specifications from a Django Rest Framework API. Compatible with Django Res

Cristi Vîjdea 3k Jan 6, 2023
Django REST API with React BoilerPlate

This is a setup of Authentication and Registration Integrated with React.js inside the Django Templates for web apps

Faisal Nazik 91 Dec 30, 2022
Introduction to Django Rest Framework

Introduction to Django Rest Framework This is the repository of the video series Introduction to Django Rest Framework published on YouTube. It is a s

Simple is Better Than Complex 20 Jul 14, 2022
Scaffold django rest apis like a champion 🚀

scaffold django rest apis like a champion ??

Abdenasser Elidrissi 133 Jan 5, 2023
JSON:API support for Django REST framework

JSON:API and Django REST framework Overview JSON:API support for Django REST framework Documentation: https://django-rest-framework-json-api.readthedo

null 1k Dec 27, 2022
DRF-extensions is a collection of custom extensions for Django REST Framework

Django REST Framework extensions DRF-extensions is a collection of custom extensions for Django REST Framework Full documentation for project is avail

Gennady Chibisov 1.3k Dec 28, 2022
Generate Views, Serializers, and Urls for your Django Rest Framework application

DRF Generators Writing APIs can be boring and repetitive work. Don't write another CRUDdy view in Django Rest Framework. With DRF Generators, one simp

Tobin Brown 332 Dec 17, 2022
A light REST library for Django.

django-nap Read The Docs: https://django-nap.readthedocs.io/en/latest/ Change log: https://django-nap.readthedocs.io/en/latest/changelog.html An API l

Curtis Maloney 223 Dec 7, 2022
Swagger Documentation Generator for Django REST Framework: deprecated

Django REST Swagger: deprecated (2019-06-04) This project is no longer being maintained. Please consider drf-yasg as an alternative/successor. I haven

Marc Gibbons 2.6k Dec 23, 2022
Document Web APIs made with Django Rest Framework

DRF Docs Document Web APIs made with Django Rest Framework. View Demo Contributors Wanted: Do you like this project? Using it? Let's make it better! S

Manos Konstantinidis 626 Nov 20, 2022
Recursive Serialization for Django REST framework

djangorestframework-recursive Overview Recursive Serialization for Django REST framework This package provides a RecursiveField that enables you to se

null 336 Dec 28, 2022
Dropdown population implementation for Django REST Framework

drf-dropdown Dropdown population implementation for Django REST Framework Usage Add DropdownView to API URL # urls.py import dropdown urlpatterns = [

Preeti Yuankrathok 4 Dec 6, 2022