Authentication for Django Rest Framework

Overview

Dj-Rest-Auth

<iMerica> Coverage Status

Drop-in API endpoints for handling authentication securely in Django Rest Framework. Works especially well with SPAs (e.g React, Vue, Angular), and Mobile applications.

Requirements

  • Django 2 or 3
  • Python 3

Quick Setup

Install package

pip install dj-rest-auth

Add dj_rest_auth app to INSTALLED_APPS in your django settings.py:

INSTALLED_APPS = (
    ...,
    'rest_framework',
    'rest_framework.authtoken',
    ...,
    'dj_rest_auth'
)

Add URL patterns

urlpatterns = [
    url(r'^dj-rest-auth/', include('dj_rest_auth.urls'))
]

(Optional) Use Http-Only cookies

REST_USE_JWT = True
JWT_AUTH_COOKIE = 'jwt-auth'

Testing

To run the tests within a virtualenv, run python runtests.py from the repository directory. The easiest way to run test coverage is with coverage, which runs the tests against all supported Django installs. To run the test coverage within a virtualenv, run coverage run ./runtests.py from the repository directory then run coverage report.

Tox

Testing may also be done using tox, which will run the tests against all supported combinations of python and django.

Install tox, either globally or within a virtualenv, and then simply run tox from the repository directory. As there are many combinations, you may run them in parallel using tox --parallel.

The tox.ini includes an environment for testing code coverage and you can run it and view this report with tox -e coverage.

Linting may also be performed via flake8 by running tox -e flake8.

Documentation

View the full documentation here: https://dj-rest-auth.readthedocs.io/en/latest/index.html

Acknowledgements

This project began as a fork of django-rest-auth. Big thanks to everyone who contributed to that repo!

Comments
  • Migrate to GitHub Actions.

    Migrate to GitHub Actions.

    Travis CI has a new pricing model which places limits on open source.

    • https://blog.travis-ci.com/2020-11-02-travis-ci-new-billing
    • https://www.jeffgeerling.com/blog/2020/travis-cis-new-pricing-plan-threw-wrench-my-open-source-works

    Many projects are moving to GitHub Actions instead, including Jazzband projects

    • https://github.com/orgs/jazzband/projects/1
    • https://github.com/jazzband-roadies/help/issues/206

    This is based on https://github.com/jazzband/contextlib2/pull/26.

    TODO:

    • [x] @jezdez to add JAZZBAND_RELEASE_KEY to the repo secrets.
    • [x] @jezdez to add @iMerica as project lead (refs #1).
    opened by jezdez 23
  • Password Reset Custom Email

    Password Reset Custom Email

    Hey everyone! Sorry if this seems repetitive but I really did try to get this to work the best I could using the solutions above. Nothing seems to work and I'm hitting a wall.

    I am trying to simply customize the email sent when the password-reset route is hit. I want it to direct to a route in my frontend (React).

    I tried @mohmyo solution to customize the email here https://github.com/iMerica/dj-rest-auth/issues/9#issuecomment-598963520.

    This doesn't seem to do a thing sadly.

    Here's some code from my project:

    project/users/serializers.py - This is my custom serializer:

    from dj_rest_auth.serializers import PasswordResetSerializer
    
    class CustomPasswordResetSerializer(PasswordResetSerializer):
        def get_email_options(self):
            return {
                'email_template_name': 'registration/password_reset_message.html'
            }
    

    project/users/urls.py - users is a app

    from dj_rest_auth.registration.views import (ConfirmEmailView, RegisterView,
                                                 VerifyEmailView)
    from dj_rest_auth.views import LoginView, LogoutView
    from django.urls import path, re_path
    
    urlpatterns = [
        path('register/', RegisterView.as_view()),
        path('account-confirm-email/<str:key>/', ConfirmEmailView.as_view()),
        path('login/', LoginView.as_view()),
        path('logout/', LogoutView.as_view()),
        path('verify-email/',
             VerifyEmailView.as_view(), name='rest_verify_email'),
        path('account-confirm-email/',
             VerifyEmailView.as_view(), name='account_email_verification_sent'),
        re_path(r'^account-confirm-email/(?P<key>[-:\w]+)/$',
                VerifyEmailView.as_view(), name='account_confirm_email'),
    ]
    
    

    project/mysite/urls.py - mysite is the directory where settings.py and the the main urls.py are:

    from dj_rest_auth.views import PasswordResetConfirmView, PasswordResetView
    from django.contrib import admin
    from django.urls import include, path
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/users/', include('users.urls')),
        path('api/users/password-reset/', PasswordResetView.as_view()),
        path('api/users/password-reset-confirm/<uidb64>/<token>/',
             PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    ]
    
    

    project/mysite/settings.py

    TEMPLATES = [
        {
            ...
            'DIRS': [os.path.join(BASE_DIR, "templates")],
            ...
        }
    ]
    
    # Django All Auth config
    EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
    AUTHENTICATION_BACKENDS = (
        "django.contrib.auth.backends.ModelBackend",
        "allauth.account.auth_backends.AuthenticationBackend",
    )
    SITE_ID = 1
    ACCOUNT_EMAIL_REQUIRED = True
    ACCOUNT_USERNAME_REQUIRED = False
    ACCOUNT_SESSION_REMEMBER = True
    ACCOUNT_AUTHENTICATION_METHOD = 'email'
    ACCOUNT_UNIQUE_EMAIL = True
    ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
    ACCOUNT_CONFIRM_EMAIL_ON_GET = True
    LOGIN_URL = 'http://localhost:8000/api/v1/users/login/'
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_USE_TLS = True
    EMAIL_HOST = local_settings.email_host
    EMAIL_HOST_USER = local_settings.email_host_user
    EMAIL_HOST_PASSWORD = local_settings.email_host_password
    EMAIL_PORT = local_settings.email_port
    
    REST_AUTH_SERIALIZERS = {
        'PASSWORD_RESET_SERIALIZER': 'users.serializers.CustomPasswordResetSerializer'
    }
    
    

    I have a template in project/templates/registration/password_reset_message.py.

    This is my file structure if it helps.

    ├── manage.py ├── templates │   └── registration │   └── password_reset_message.html ├── mysite │   ├── init.py │   ├── asgi.py │   ├── local_settings.py │   ├── settings.py │   ├── urls.py │   └── wsgi.py └── users ├── init.py ├── admin.py ├── apps.py ├── forms.py ├── migrations │   ├── 0001_initial.py │   └── init.py ├── models.py ├── serializers.py ├── tests.py ├── urls.py └── views.py

    The issue is the template I specify isn't being sent. Rather, the default one provide by Django is.

    I tried the other way in @mohmyo solution as well where you overwrite the entire save method of the serializer with no luck. Thanks to anyone who can help out here. This is my first GitHub issue!

    opened by tarricsookdeo 14
  • Password reset throws error with django 3.1

    Password reset throws error with django 3.1

    Hello,

    recently updated django to version 3.1 and the password reset view throws error: django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' with keyword arguments '{'uidb64': 'MTA', 'token': 'a88hdr-5fb0f72acbe1e9d2b81b7810dee31037'}' not found. 1 pattern(s) tried: ['usermanagement\/password-reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$']

    If i roll back to django 3.0 it works again.

    bug 
    opened by IIFelix 14
  • UID for password reset incorrectly uses base64

    UID for password reset incorrectly uses base64

    When a password reset link is request, the UID is encoded into the url as such, by django allauth

    /accounts/password/reset/key/7w-1x7-d1a11z1sa1s1a1s/
    

    Such that the uid is 7w and the token is 1x7-d1a11z1sa1s1a1s

    The UID is encoded here, as base36: https://github.com/pennersr/django-allauth/blob/330bf899dd77046fd0510221f3c12e69eb2bc64d/allauth/account/forms.py#L524

    However, when the UID decoded in django-rest-auth as base64 https://github.com/jazzband/dj-rest-auth/blob/02c9242e3d069164692ef44a0f15eaca31a41cac/dj_rest_auth/serializers.py#L214

    question 
    opened by gsheni 14
  • ImproperlyConfigured registration email verification

    ImproperlyConfigured registration email verification

    hi! when I try to access the following link in the email confirmation sent on user registration:

    http://localhost:8000/dj-rest-auth/registration/account-confirm-email/MQ:1jIgPr:Ayckd0pouL4B-foYgl2wjdSCYOY/

    I receive the following error:

    ImproperlyConfigured
    TemplateResponseMixin requires either a definition of 'template_name' or an implementation of 'get_template_names()'
    

    Where should I create such a template? how should I name the template? it would be great if you could point me to some documentation or shed some light on how to proceed further. cheers!

    opened by fessacchiotto 14
  • Authenticate on a backend server with Google account

    Authenticate on a backend server with Google account

    Hello, I already have dj-rest-auth in my app. How can I authenticate user on a backend server with Google account - https://developers.google.com/identity/sign-in/android/backend-auth

    I dont want to reinvent the wheel, maybe you could point me out how to do this with dj-rest-auth Thanks in advance!

    support-request 
    opened by bene25 11
  • Google Social Authentication with dj-rest-auth

    Google Social Authentication with dj-rest-auth

    I've spent a a lot of time on implementing Google oAuth with dj-rest-auth which should be easier, and I'll post my solution here, hoping it'll help somebody else. views.py

    class GoogleLogin(SocialLoginView):
        adapter_class = GoogleOAuth2Adapter
        client_class = OAuth2Client
        callback_url = "http://127.0.0.1:8000/api/auth/google/callback/"
    

    urls.py

    path(r'auth/google', GoogleLogin.as_view(), name='google_login')

    settings.py

       'allauth.socialaccount',
       'allauth.socialaccount.providers.google',
    

    The callback_url and client_class are only required if you're sending only code i.e. authorization_code to Google oAuth URL. The problem I had was that after making the request to https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=<callback-url>&prompt=consent&response_type=code&client_id=<your_client_id>&scope=openid%20email&access_type=offline (change the callback_url and client_id with the ones from your app), as a response I got back the code. When sending the code to the /auth/google URL, i got this error Error retrieving access token: b'{\n “error”: “redirect_uri_mismatch”,\n “error_description”: “Bad Request”\n}'. This was because the code is URL safe, which means you'll need to first decode it and then send it to your API endpoint.

    opened by MatejMijoski 10
  • Sign In with Apple KeyError: 'id_token'

    Sign In with Apple KeyError: 'id_token'

    I want to start off by saying fantastic job on this package.

    An issue was raised on StackOverflow last week about Sign In with Apple and rest-auth here that is not seeing much traffic. This issue seems to be the same with dj-rest-framework.

    Following the example, this is what I got:

    from allauth.socialaccount.providers.apple.views import AppleOAuth2Adapter
    from allauth.socialaccount.providers.apple.client import AppleOAuth2Client
    from dj_rest_auth.registration.views import SocialLoginView
    
    class AppleLogin(SocialLoginView):
        """
        Class used for Sign In with Apple authentication.
        """
        adapter_class = AppleOAuth2Adapter
        client_class = AppleOAuth2Client
        callback_url = 'example.com'
    

    Submitting the access_token and code, you get the same KeyError: 'id_token' (targeting the same line) that is mentioned in the Stack Overflow question.

    When using Django allauth exclusively, Sign In with Apple works. It's only over the API requests that it does not.

    Thanks for the help.

    opened by gabe-lucas 10
  • Refresh token not blacklisted on logout

    Refresh token not blacklisted on logout

    #27

    Attempt to blacklist refresh token if no JWT_AUTH_COOKIE is found and using SimpleJWT Blacklist

    Status returned may be questionable in my try/except, but they make sense to me. I'm not sure how the cookies work, so I didn't test that. If there is a better way to implement this (should it be blacklisted even if using cookies?), please let me know!

    enhancement 
    opened by mjlabe 10
  • ImportError: djangorestframework_jwt needs to be installed

    ImportError: djangorestframework_jwt needs to be installed

    When using rest_framework_simplejwt, I am getting ImportError: djangorestframework_jwt needs to be installed when I hit login or registration.

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',
        'rest_framework_simplejwt.token_blacklist',
        'dj_rest_auth',
        'django.contrib.sites',
        'allauth',
        'allauth.account',
        'dj_rest_auth.registration',
        ...
    ]
    
    REST_FRAMEWORK = {
        # Use Django's standard `django.contrib.auth` permissions,
        # or allow read-only access for unauthenticated users.
        'DEFAULT_PERMISSION_CLASSES': [
            'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
        ],
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework_simplejwt.authentication.JWTAuthentication',
        )
    }
    
    REST_USE_JWT = True
    
    opened by mjlabe 10
  • Login/Logout API endpoints not sending/clearing django sessionid cookie

    Login/Logout API endpoints not sending/clearing django sessionid cookie

    EDITED TLDR: Part of the problem was that I was not including credentials on my frontend, and this got the login method working. However, I am still unable to get the logout function to work

    I have followed the installation instructions, and am trying to use dj-rest-auth with a react SPA. It appears to be partly working, as when I log in via the django admin console, and I make a GET request to /api/account/user/ (my user endpoint for dj-rest-auth), I get back the user info which corresponds to my user. This makes me think nothing is wrong with at least the basic configuration of dj-rest-auth. When I log out from the admin console and hit the same endpoint, I get a 403 response with a JSON response that tells me no user is logged in. Great.

    However, the login/logout endpoints don't appear to be working. When I log in via the django admin console, and then I hit the logout endpoint with my SPA, it does not log me out. The django server tells me the request was good:

    [21/Oct/2022 17:32:18] "POST /api/account/logout/ HTTP/1.0" 200 37
    

    But I am still logged in to the console, and no change was made to the Session model database.

    Similarly, when I hit the login endpoint with a POST request, using exactly the same username/password as I use in the admin console, it does not log me in. However, the login request gives me back a 200 response:

    [21/Oct/2022 17:39:58] "POST /api/account/login/ HTTP/1.0" 200 50
    

    which seems odd. dj-rest-auth seems to think that it's working, but for some reason it doesn't appear to be attaching / detaching users from sessions. Any ideas as to why this might be, or how to debug it further?

    opened by edmundsj 9
  • allauth's openid connect

    allauth's openid connect

    Hello, django-allauth now support openid connect. This allows one provider class to support theoretically any OIDC compliant service. It could even perhaps replace every other provider.

    Is supporting this something the project would want? If so, may have time to help. The challenge is that this provider can be added multiple times using a SERVERS array and then generates a "dynamic instance for each configured server". This is very different as other providers can only be used once and have a static provider ID ("google"). Example:

    Provider class id: openid_connect Provider server id: google_oidc Provider server id: another_oidc

    Without changes, various places get the wrong ID. For example a callback url ends up having openid_connect when it really should have google_oidc. I got a terrible version working already by forcing in the dynamic provider name into various places. I would need to rework it for it to be of acceptable quality for this project.

    Let me know if you think this is worth my time to create a pull request for. IMO OIDC is nice because I can forget about every provider and use just 1 for everything. I no longer would need to make a custom provider class just to support yet another oauth2 service. I can also add multiple providers - for example I can add two Azure tenants to one site (impossible previously with allauth). That said, I would understand if supporting every allauth socialaccount feature isn't appetizing here.

    opened by bufke 0
  • httponly default incorrect in views.py

    httponly default incorrect in views.py

    The default for HTTPOnly is incorrect in the views.py on line #92:

    if getattr(settings, 'REST_USE_JWT', False):
        from .jwt_auth import set_jwt_cookies
        set_jwt_cookies(response, self.access_token, self.refresh_token)`
    

    Further, the HTTPOnly should be included in the serializer; no reason to remove it. This will simplify the code and also allow for easier testing. This can be seen on lines 99-103.

    opened by donaic 0
  • LogoutView return 500 status, when refresh token is invalid and output language is not English

    LogoutView return 500 status, when refresh token is invalid and output language is not English

    At BlacklistMixin you use gettext for raise TokenError with message "Token is blacklisted". But in LogoutView at checking error message at args array, you don`t use gettext, so if condition return False, when current language is not English

    image

    image

    opened by top1Dron 0
  • Login immediately on register when using JWT HTTP only

    Login immediately on register when using JWT HTTP only

    Hi there,

    Is there a way to have a user logged in immediately on register? I have set ACCOUNT_EMAIL_VERIFICATION = 'optional' and want the flow to have a user logged in once they register (then verify email at their convinience), but the register view doesn't set the JWT cookies so the user is still required to hit the Login view separately after registering...

    Is there a configuration or adjustment I can make to log in a user with JWT immediately after they register?

    Thanks :)

    opened by ainthateasy 0
  • Login only with email not working

    Login only with email not working

    I'm trying to enable our users to login either with their username or email, but not both. I followed #126 and the username-only login works fine, but the email-only login fails with: "Unable to login with the provided credentials.". This fails both when using email and username_email as the config value of ACCOUNT_AUTHENTICATION_METHOD.

    My account-related settings are:

    ACCOUNT_USERNAME_REQUIRED = True
    ACCOUNT_DEFAULT_HTTP_PROTOCOL = env(
        "BACKEND_ACCOUNT_DEFAULT_HTTP_PROTOCOL", default="http"
    )
    ACCOUNT_EMAIL_REQUIRED = True
    ACCOUNT_EMAIL_VERIFICATION = "mandatory"
    ACCOUNT_CONFIRM_EMAIL_ON_GET = True
    ACCOUNT_UNIQUE_EMAIL = True
    
    # Allows users to login either
    # by username or email.
    ACCOUNT_AUTHENTICATION_METHOD = "username_email"
    
    opened by ifigueroap 0
  • Google OAuth Redirect Uri Missmatch error, but urls seem to be configured correctly

    Google OAuth Redirect Uri Missmatch error, but urls seem to be configured correctly

    1. On my frontend (ReactJs) I'm login using Google and getting the "code" using the Auth Code Flow which looks something like this:
    {
        "code": "4/0AfteXvtM-2XB5q-cTe-l-oYTkkRg-3QZf8V44cEvrRvCpPR9gSXhn76dF-oU2SPxDNvSpw",
        "scope": "email profile openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
        "authuser": "0",
        "prompt": "consent"
    }
    
    1. Then I'm sending this in the body of a POST request to my DRF API which lands on this view:
    class GoogleLogin(SocialLoginView):
        adapter_class = GoogleOAuth2Adapter
        client_class = OAuth2Client
        callback_url = 'http://localhost:8000/accounts/google/login/callback/'
    
    1. In my Google Console I have the same callback URL setup under OAuth 2.0 Client IDs: image

    2. But I keep getting the same error:

    Error retrieving access token: {
        "error": "redirect_uri_mismatch",
        "error_description": "Bad Request"
    }
    
    opened by adrenaline681 0
Releases(2.2.5)
Owner
Michael
Lead Software Engineer, Founder - Platform & Product
Michael
Foundation Auth Proxy is an abstraction on Foundations' authentication layer and is used to authenticate requests to Atlas's REST API.

foundations-auth-proxy Setup By default the server runs on http://0.0.0.0:5558. This can be changed via the arguments. Arguments: '-H' or '--host': ho

Dessa - Open Source 2 Jul 03, 2020
Creation & manipulation of PyPI tokens

PyPIToken: Manipulate PyPI API tokens PyPIToken is an open-source Python 3.6+ library for generating and manipulating PyPI tokens. PyPI tokens are ver

Joachim Jablon 8 Nov 01, 2022
This script helps you log in to your LMS account and enter the currently running session

This script helps you log in to your LMS account and enter the currently running session, all in a second

Ali Ebrahimi 5 Sep 01, 2022
Kube OpenID Connect is an application that can be used to easily enable authentication flows via OIDC for a kubernetes cluster

Kube OpenID Connect is an application that can be used to easily enable authentication flows via OIDC for a kubernetes cluster. Kubernetes supports OpenID Connect Tokens as a way to identify users wh

7 Nov 20, 2022
Django Rest Framework App wih JWT Authentication and other DRF stuff

Django Queries App with JWT authentication, Class Based Views, Serializers, Swagger UI, CI/CD and other cool DRF stuff API Documentaion /swagger - Swa

Rafael Salimov 4 Jan 29, 2022
AddressBookApp - Address Book App in Django

AddressBookApp Application Name Address Book App in Django, 2022 Technologies La

Joshua K 1 Aug 18, 2022
A fully tested, abstract interface to creating OAuth clients and servers.

Note: This library implements OAuth 1.0 and not OAuth 2.0. Overview python-oauth2 is a python oauth library fully compatible with python versions: 2.6

Joe Stump 3k Jan 02, 2023
Awesome Django authorization, without the database

rules rules is a tiny but powerful app providing object-level permissions to Django, without requiring a database. At its core, it is a generic framew

1.6k Dec 30, 2022
This is a Token tool that gives you many options to harm the account.

Trabis-Token-Tool This is a Token tool that gives you many options to harm the account. Utilities With this tools you can do things as : ·Delete all t

Steven 2 Feb 13, 2022
JSON Web Token implementation in Python

PyJWT A Python implementation of RFC 7519. Original implementation was written by @progrium. Sponsor If you want to quickly add secure token-based aut

José Padilla 4.5k Jan 09, 2023
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
Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication.

Welcome to django-allauth! Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (soc

Raymond Penners 7.7k Jan 03, 2023
An introduction of Markov decision process (MDP) and two algorithms that solve MDPs (value iteration, policy iteration) along with their Python implementations.

Markov Decision Process A Markov decision process (MDP), by definition, is a sequential decision problem for a fully observable, stochastic environmen

Yu Shen 31 Dec 30, 2022
Python module for generating and verifying JSON Web Tokens

python-jwt Module for generating and verifying JSON Web Tokens. Note: From version 2.0.1 the namespace has changed from jwt to python_jwt, in order to

David Halls 210 Dec 24, 2022
it's a Django application to register and authenticate users using phone number.

django-phone-auth It's a Django application to register and authenticate users using phone number. CustomUser model created using AbstractUser class.

MsudD 4 Nov 29, 2022
Authentication Module for django rest auth

django-rest-knox Authentication Module for django rest auth Knox provides easy to use authentication for Django REST Framework The aim is to allow for

James McMahon 878 Jan 04, 2023
Mock authentication API that acceccpts email and password and returns authentication result.

Mock authentication API that acceccpts email and password and returns authentication result.

Herman Shpryhau 1 Feb 11, 2022
A simple username/password database authentication solution for Streamlit

TL;DR: This is a simple username/password login authentication solution using a backing database. Both SQLite and Airtable are supported.

Arvindra 49 Nov 25, 2022
Toolkit for Pyramid, a Pylons Project, to add Authentication and Authorization using Velruse (OAuth) and/or a local database, CSRF, ReCaptcha, Sessions, Flash messages and I18N

Apex Authentication, Form Library, I18N/L10N, Flash Message Template (not associated with Pyramid, a Pylons project) Uses alchemy Authentication Authe

95 Nov 28, 2022
Automatizando a criação de DAGs usando Jinja e YAML

Automatizando a criação de DAGs no Airflow usando Jinja e YAML Arquitetura do Repo: Pastas por contexto de negócio (ex: Marketing, Analytics, HR, etc)

Arthur Henrique Dell' Antonia 5 Oct 19, 2021