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
Django Admin Two-Factor Authentication, allows you to login django admin with google authenticator.

Django Admin Two-Factor Authentication Django Admin Two-Factor Authentication, allows you to login django admin with google authenticator. Why Django

Iman Karimi 9 Dec 07, 2022
Strong, Simple, and Precise security for Flask APIs (using jwt)

flask-praetorian Strong, Simple, and Precise security for Flask APIs API security should be strong, simple, and precise like a Roman Legionary. This p

Tucker Beck 321 Dec 18, 2022
Phishing Abusing Microsoft 365 OAuth Authorization Flow

Microsoft365_devicePhish Abusing Microsoft 365 OAuth Authorization Flow for Phishing Attack This is a simple proof-of-concept script that allows an at

bigb0ss 11 Dec 11, 2022
This Python based program checks your CC Stripe Auth 1$ Based Checker

CC-Checker This Python based program checks your CC Stripe Auth 1$ Based Checker About Author Coded by xBlackx Reach Me On Telegram @xBlackx_Coder jOI

xBlackxCoder 11 Nov 20, 2022
Accounts for Django made beautifully simple

Django Userena Userena is a Django application that supplies your Django project with full account management. It's a fully customizable application t

Bread & Pepper 1.3k Sep 18, 2022
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 Jan 03, 2023
Easy and secure implementation of Azure AD for your FastAPI APIs 🔒 Single- and multi-tenant support.

Easy and secure implementation of Azure AD for your FastAPI APIs 🔒 Single- and multi-tenant support.

Intility 220 Jan 05, 2023
Login-python - Login system made in Python, using native libraries

login-python Sistema de login feito 100% em Python, utilizando bibliotecas nativ

Nicholas Gabriel De Matos Leal 2 Jan 28, 2022
Authentication testing framework

What is this This is a framework designed to test authentication for web applications. While web proxies like ZAProxy and Burpsuite allow authenticate

DigeeX 140 Jul 06, 2022
A Python inplementation for OAuth2

OAuth2-Python Discord Inplementation for OAuth2 login systems. This is a simple Python 'app' made to inplement in your programs that require (shitty)

Prifixy 0 Jan 06, 2022
Generate payloads that force authentication against an attacker machine

Hashgrab Generates scf, url & lnk payloads to put onto a smb share. These force authentication to an attacker machine in order to grab hashes (for exa

xct 35 Dec 20, 2022
The ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS,JWE,JWK,JWA,JWT included.

Authlib The ultimate Python library in building OAuth and OpenID Connect servers. JWS, JWK, JWA, JWT are included. Authlib is compatible with Python2.

Hsiaoming Yang 3.4k Jan 04, 2023
An open source Flask extension that provides JWT support (with batteries included)!

Flask-JWT-Extended Features Flask-JWT-Extended not only adds support for using JSON Web Tokens (JWT) to Flask for protecting views, but also many help

Landon Gilbert-Bland 1.4k Jan 04, 2023
Social auth made simple

Python Social Auth Python Social Auth is an easy-to-setup social authentication/registration mechanism with support for several frameworks and auth pr

Matías Aguirre 2.8k Dec 24, 2022
A flask extension for managing permissions and scopes

Flask-Pundit A simple flask extension to organize resource authorization and scoping. This extension is heavily inspired by the ruby Pundit library. I

Anurag Chaudhury 49 Dec 23, 2022
This project is an open-source project which I made due to sharing my experience around the Python programming language.

django-tutorial This project is an open-source project which I made due to sharing my experience around the Django framework. What is Django? Django i

MohammadMasoumi 6 May 12, 2022
Django x Elasticsearch Templates

Django x Elasticsearch Requirements Python 3.7 Django = 3 Elasticsearch 7.15 Setup Elasticsearch Install via brew Install brew tap elastic/tap brew

Aji Pratama 0 May 22, 2022
Simple yet powerful authorization / authentication client library for Python web applications.

Authomatic Authomatic is a framework agnostic library for Python web applications with a minimalistic but powerful interface which simplifies authenti

1k Dec 28, 2022
PetitPotam - Coerce NTLM authentication from Windows hosts

Python implementation for PetitPotam

ollypwn 137 Dec 28, 2022
Quick and simple security for Flask applications

Note This project is non maintained anymore. Consider the Flask-Security-Too project as an alternative. Flask-Security It quickly adds security featur

Matt Wright 1.6k Dec 19, 2022