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 = [
    path('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
  • Update 2.2.6 broke Google login

    Update 2.2.6 broke Google login

    Trace : site-packages/dj_rest_auth/registration/serializers.py, line 150, in validate

    -> login = self.get_social_login(adapter, app, social_token, token)

    site-packages/dj_rest_auth/registration/serializers.py, line 60, in get_social_login

    -> social_login = adapter.complete_login(request, app, token, response=response)

    site-packages/allauth/socialaccount/providers/google/views.py, line 23, in complete_login

    try: identity_data = jwt.decode( -> response["id_token"], …

    Error : TypeError : string indices must be integers, not 'str'.

    The response is not a dict but instead it's a string of some id which then i tried and got : OAuth2Error("Invalid id_token")

    opened by Altroo 0
  • `SocialConnectView.process_login()` should not perform login

    `SocialConnectView.process_login()` should not perform login

    process_login() in SocialConnectView try to issue a new session tied to the specified social account (when REST_SESSION_LOGIN is True), but I think this behavior is not expected especially when the social account already exists in the DB:

    1. Signup and login as a User 1 tied to a SocialAccount 1
    2. Logout
    3. Signup and login as a User 2 tied to a SocialAccount 2
    4. Run a /connect API for User 2 with SocialAccount 1
    5. _add_social_account will reject the operation
    6. SocialConnectView runs django_login() and refreshes the user's session with a new one tied to User 1 even if the connection is failed

    Ref. #25.

    opened by okapies 0
  • 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 2
  • 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
Releases(2.2.6)
Owner
Michael
Lead Software Engineer, Founder - Platform & Product
Michael
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 Django-powered API with various utility apps / endpoints.

A Django-powered API Includes various utility apps / endpoints. Demos These web apps provide a frontend to the APIs in this project. Issue API Explore

Shemar Lindie 0 Sep 13, 2021
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
A RESTful way to use your Notion tables as a database.

rest-notion-db A RESTful way to use your Notion tables as a database. Use-cases Form submissions or frontend websites, use one database that

Oorjit Chowdhary 42 Dec 27, 2022
Built on Django Rest Framework, to provide with command execution on linux terminal

Built on Django Rest Framework, to provide with command execution on linux terminal

1 Oct 31, 2021
Turn your API made with Django REST Framework(DRF) into a GraphQL like API.

Turn your API made with Django REST Framework(DRF) into a GraphQL like API.

Yezy Ilomo 575 Jan 05, 2023
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 04, 2023
Django-rest-auth provides a set of REST API endpoints for Authentication and Registration

This app makes it extremely easy to build Django powered SPA's (Single Page App) or Mobile apps exposing all registration and authentication related functionality as CBV's (Class Base View) and REST

Tivix 2.4k Dec 29, 2022
Automatically generate a RESTful API service for your legacy database. No code required!

sandman2 sandman2 documentation [ ~ Dependencies scanned by PyUp.io ~ ] sandman2 automagically generates a RESTful API service from your existing data

Jeff Knupp 1.9k Jan 07, 2023
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
BloodDonors: Built using Django REST Framework for the API backend and React for the frontend

BloodDonors By Daniel Yuan, Alex Tian, Aaron Pan, Jennifer Yuan As the pandemic raged, one of the side effects was an urgent shortage of blood donatio

Daniel Yuan 1 Oct 24, 2021
Integrate GraphQL into your Django project.

Graphene-Django A Django integration for Graphene. 💬 Join the community on Slack Documentation Visit the documentation to get started! Quickstart For

GraphQL Python 4k Dec 31, 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
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
The no-nonsense, minimalist REST and app backend framework for Python developers, with a focus on reliability, correctness, and performance at scale.

The Falcon Web Framework Falcon is a reliable, high-performance Python web framework for building large-scale app backends and microservices. It encou

Falconry 9k Jan 03, 2023
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 873 Dec 30, 2022
Key-Value база данных на Tarantool и REST API к ней.

KVmail Key-Value база данных на Tarantool и REST API к ней. Документация к API доступна здесь. Requiremrnts ubuntu 16.04+ python3.6+ supervisord nginx

1 Jun 16, 2021
Extensions for Django REST Framework

Extensions for Django REST Framework

aiden 6 Dec 27, 2022
Kong API Manager with Prometheus And Splunk

API Manager Stack Run Kong Server + Konga + Prometheus + Grafana + API & DDBB + Splunk Clone the proyect and run docker-compose up

Santiago Fernandez 82 Nov 26, 2022
REST API framework designed for human beings

Eve Eve is an open source Python REST API framework designed for human beings. It allows to effortlessly build and deploy highly customizable, fully f

eve 6.6k Jan 04, 2023