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
User Authentication in Flask using Flask-Login

User-Authentication-in-Flask Set up & Installation. 1 .Clone/Fork the git repo and create an environment Windows git clone https://github.com/Dev-Elie

ONDIEK ELIJAH OCHIENG 31 Dec 11, 2022
Minimal authorization through OO design and pure Ruby classes

Pundit Pundit provides a set of helpers which guide you in leveraging regular Ruby classes and object oriented design patterns to build a simple, robu

Varvet 7.8k Jan 02, 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

Simple JWT 3.3k Jan 01, 2023
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
API-key based security utilities for FastAPI, focused on simplicity of use

FastAPI simple security API key based security package for FastAPI, focused on simplicity of use: Full functionality out of the box, no configuration

Tolki 154 Jan 03, 2023
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
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
API with high performance to create a simple blog and Auth using OAuth2 ⛏

DogeAPI API with high performance built with FastAPI & SQLAlchemy, help to improve connection with your Backend Side to create a simple blog and Cruds

Yasser Tahiri 111 Jan 05, 2023
Beihang University Network Authentication Login

北航自动网络认证使用说明 主文件 gw_buaa.py # @file gw_buaa.py # @author Dong # @date 2022-01-25 # @email windcicada 0 Jul 22, 2022

OpenStack Keystone auth plugin for HTTPie

httpie-keystone-auth OpenStack Keystone auth plugin for HTTPie. Installation $ pip install --upgrade httpie-keystone-auth You should now see keystone

Pavlo Shchelokovskyy 1 Oct 20, 2021
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
OAuthlib support for Python-Requests!

Requests-OAuthlib This project provides first-class OAuth library support for Requests. The OAuth 1 workflow OAuth 1 can seem overly complicated and i

1.6k Dec 28, 2022
A Python package, that allows you to acquire your RecNet authorization bearer token with your account credentials!

RecNet-Login This is a Python package, that allows you to acquire your RecNet bearer token with your account credentials! Installation Done via git: p

Jesse 6 Aug 18, 2022
Object Moderation Layer

django-oml Welcome to the documentation for django-oml! OML means Object Moderation Layer, the idea is to have a mixin model that allows you to modera

Angel Velásquez 12 Aug 22, 2019
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
Boilerplate/Starter Project for building RESTful APIs using Flask, SQLite, JWT authentication.

auth-phyton Boilerplate/Starter Project for building RESTful APIs using Flask, SQLite, JWT authentication. Setup Step #1 - Install dependencies $ pip

sandhika 0 Aug 03, 2022
Python library for generating a Mastercard API compliant OAuth signature.

oauth1-signer-python Table of Contents Overview Compatibility References Usage Prerequisites Adding the Library to Your Project Importing the Code Loa

23 Aug 01, 2022
Corsair_scan is a security tool to test Cross-Origin Resource Sharing (CORS).

Welcome to Corsair_scan Corsair_scan is a security tool to test Cross-Origin Resource Sharing (CORS) misconfigurations. CORS is a mechanism that allow

Santander Security Research 116 Nov 09, 2022
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 (JSON)

Welcome to django-rest-auth Repository is unmaintained at the moment (on pause). More info can be found on this issue page: https://github.com/Tivix/d

Tivix 2.4k Jan 03, 2023
Flask user session management.

Flask-Login Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users

Max Countryman 3.2k Dec 28, 2022