Welcome to djoser’s documentation!

Introduction

REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such as registration, login, logout, password reset and account activation. It works with custom user model.

Instead of reusing Django code (e.g. PasswordResetForm), we reimplemented few things to fit better into Single Page App architecture.

Developed by SUNSCRAPERS with passion & patience.

Getting started

Available endpoints

  • /users/
  • /users/me/
  • /users/confirm/
  • /users/change_username/
  • /password/
  • /password/reset/
  • /password/reset/confirm/
  • /token/login/ (Token Based Authentication)
  • /token/logout/ (Token Based Authentication)
  • /jwt/create/ (JSON Web Token Authentication)
  • /jwt/refresh/ (JSON Web Token Authentication)
  • /jwt/verify/ (JSON Web Token Authentication)

Supported authentication backends

Supported Python versions

  • Python 2.7
  • Python 3.4
  • Python 3.5
  • Python 3.6

Supported Django versions

  • Django 1.11
  • Django 2.0

Supported Django Rest Framework versions

  • Django Rest Framework 3.7

Installation

$ pip install -U djoser

If you are going to use JWT authentication, you will also need to install djangorestframework_simplejwt with:

$ pip install -U djangorestframework_simplejwt

Finally if you are going to use third party based authentication e.g. facebook, you will need to install social-auth-app-django with:

$ pip install -U social-auth-app-django

Configuration

Configure INSTALLED_APPS:

INSTALLED_APPS = (
    'django.contrib.auth',
    (...),
    'rest_framework',
    'djoser',
    (...),
)

Configure urls.py:

urlpatterns = [
    (...),
    url(r'^auth/', include('djoser.urls')),
]

HTTP Basic Auth strategy is assumed by default as Django Rest Framework does it. We strongly discourage and do not provide any explicit support for basic auth. You should customize your authentication backend as described in Authentication Backends.

In case of third party based authentication PSA backend docs will be a great reference to configure given provider.

Sample usage

We provide a standalone test app for you to start easily, see how everything works with basic settings. It might be useful before integrating djoser into your backend application.

In this extremely short tutorial we are going to mimic the simplest flow: register user, log in and log out. We will also check resource access on each consecutive step. Let’s go!

Clone repository and install djoser to your virtualenv:

$ git clone git@github.com:sunscrapers/djoser.git
$ cd djoser
$ pip install -e .

Go to the testproject directory, migrate the database and start the development server:

$ cd testproject
$ ./manage.py migrate
$ ./manage.py runserver 8088

Register a new user:

$ curl -X POST http://127.0.0.1:8088/auth/users/ --data 'username=djoser&password=alpine12'
{"email": "", "username": "djoser", "id":1}

So far, so good. We have just created a new user using REST API.

Let’s access user’s details:

$ curl -LX GET http://127.0.0.1:8088/auth/users/me/
{"detail": "Authentication credentials were not provided."}

As we can see, we cannot access user profile without logging in. Pretty obvious.

Let’s log in:

curl -X POST http://127.0.0.1:8088/auth/token/login/ --data 'username=djoser&password=alpine12'
{"auth_token": "b704c9fc3655635646356ac2950269f352ea1139"}

We have just obtained an authorization token that we may use later in order to retrieve specific resources.

Let’s access user’s details again:

$ curl -LX GET http://127.0.0.1:8088/auth/users/me/
{"detail": "Authentication credentials were not provided."}

Access is still forbidden but let’s offer the token we obtained:

$ curl -LX GET http://127.0.0.1:8088/auth/users/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'
{"email": "", "username": "djoser", "id": 1}

Yay, it works!

Now let’s log out:

curl -X POST http://127.0.0.1:8088/auth/token/logout/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'

And try access user profile again:

$ curl -LX GET http://127.0.0.1:8088/auth/users/me/ -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'
{"detail": "Invalid token"}

As we can see, user has been logged out successfully and the proper token has been removed.

Authentication Backends

Note

Both Token Based and JWT Authentication can coexist at same time. Simply, follow instructions for both authentication methods and it should work.

Token Based Authentication

Add 'rest_framework.authtoken' to INSTALLED_APPS:

INSTALLED_APPS = [
    'django.contrib.auth',
    (...),
    'rest_framework',
    'rest_framework.authtoken',
    'djoser',
    (...),
]

Configure urls.py. Pay attention to djoser.url.authtoken module path:

urlpatterns = [
    (...),
    url(r'^auth/', include('djoser.urls')),
    url(r'^auth/', include('djoser.urls.authtoken')),
]

Add rest_framework.authentication.TokenAuthentication to Django REST Framework authentication strategies tuple:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        (...)
    ),
}

Run migrations - this step will create tables for auth and authtoken apps:

$ ./manage.py migrate

JSON Web Token Authentication

Django Settings

Add rest_framework_simplejwt.authentication.JWTAuthentication to Django REST Framework authentication strategies tuple:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        (...)
    ),
}

Configure django-rest-framework-simplejwt to use the Authorization: JWT <access_token> header:

SIMPLE_JWT = {
   'AUTH_HEADER_TYPES': ('JWT',),
}

urls.py

Configure urls.py with djoser.url.jwt module path:

urlpatterns = [
    (...),
    url(r'^auth/', include('djoser.urls')),
    url(r'^auth/', include('djoser.urls.jwt')),
]

Settings

You may optionally provide DJOSER settings:

DJOSER = {
    'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}',
    'ACTIVATION_URL': '#/activate/{uid}/{token}',
    'SEND_ACTIVATION_EMAIL': True,
    'SERIALIZERS': {},
}

PASSWORD_RESET_CONFIRM_URL

URL to your frontend password reset page. It should contain {uid} and {token} placeholders, e.g. #/password-reset/{uid}/{token}. You should pass uid and token to reset password confirmation endpoint.

Required: True

SEND_ACTIVATION_EMAIL

If True user will be required to click activation link sent in email after:

  • creating an account via RegistrationView
  • updating his email via UserView

Default: False

SEND_CONFIRMATION_EMAIL

If True, register or activation endpoint will send confirmation email to user.

Default: False

ACTIVATION_URL

URL to your frontend activation page. It should contain {uid} and {token} placeholders, e.g. #/activate/{uid}/{token}. You should pass uid and token to activation endpoint.

Required: True

SET_USERNAME_RETYPE

If True, you need to pass re_new_{{ User.USERNAME_FIELD }} to /{{ User.USERNAME_FIELD }}/ endpoint, to validate username equality.

Default: False

SET_PASSWORD_RETYPE

If True, you need to pass re_new_password to /password/ endpoint, to validate password equality.

Default: False

PASSWORD_RESET_CONFIRM_RETYPE

If True, you need to pass re_new_password to /password/reset/confirm/ endpoint in order to validate password equality.

Default: False

LOGOUT_ON_PASSWORD_CHANGE

If True, setting new password will logout the user.

Default: False

USER_EMAIL_FIELD_NAME

Determines which field in User model is used for email in versions of Django before 1.11. In Django 1.11 and greater value of this setting is ignored and value provided by User.get_email_field_name is used. This setting will be dropped when Django 1.8 LTS goes EOL.

Default: 'email'

PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND

If True, posting a non-existent email to /password/reset/ will return a HTTP_400_BAD_REQUEST response with an EMAIL_NOT_FOUND error message (‘User with given email does not exist.’).

If False (default), the /password/reset/ endpoint will always return a HTTP_204_NO_CONTENT response.

Please note that setting this to True will expose information whether an email is registered in the system.

Default: False

TOKEN_MODEL

Points to which token model should be used for authentication. In case if only stateless tokens (e.g. JWT) are used in project it should be set to None.

Example: 'knox.models.AuthToken' Default: 'rest_framework.authtoken.models.Token'

SERIALIZERS

Dictionary which maps djoser serializer names to paths to serializer classes. This setting provides a way to easily override given serializer(s) - it’s is used to update the defaults, so by providing, e.g. one key, all the others will stay default.

Note

Current user endpoints now use the serializer specified by SERIALIZERS.current_user. This enables better security and privacy: the serializers can be configured separately so that confidential fields that are returned to the current user are not shown in the regular user endpoints.

Examples

{
    'user': 'myapp.serializers.SpecialUserSerializer',
}

Default:

{
    'activation': 'djoser.serializers.ActivationSerializer',
    'password_reset': 'djoser.serializers.PasswordResetSerializer',
    'password_reset_confirm': 'djoser.serializers.PasswordResetConfirmSerializer',
    'password_reset_confirm_retype': 'djoser.serializers.PasswordResetConfirmRetypeSerializer',
    'set_password': 'djoser.serializers.SetPasswordSerializer',
    'set_password_retype': 'djoser.serializers.SetPasswordRetypeSerializer',
    'set_username': 'djoser.serializers.SetUsernameSerializer',
    'set_username_retype': 'djoser.serializers.SetUsernameRetypeSerializer',
    'user_create': 'djoser.serializers.UserCreateSerializer',
    'user_delete': 'djoser.serializers.UserDeleteSerializer',
    'user': 'djoser.serializers.UserSerializer',
    'current_user': 'djoser.serializers.CurrentUserSerializer',
    'token': 'djoser.serializers.TokenSerializer',
    'token_create': 'djoser.serializers.TokenCreateSerializer',
}

EMAIL

Dictionary which maps djoser email names to paths to email classes. Same as in case of SERIALIZERS it allows partial override.

Examples

{
    'activation': 'myapp.email.AwesomeActivationEmail',
}

Default:

{
    'activation': 'djoser.email.ActivationEmail',
    'confirmation': 'djoser.email.ConfirmationEmail',
    'password_reset': 'djoser.email.PasswordResetEmail',
}

SOCIAL_AUTH_TOKEN_STRATEGY

String path to class responsible for token strategy used by social authentication.

Example: 'myapp.token.MyStrategy' Default: 'djoser.social.token.jwt.TokenStrategy'

SOCIAL_AUTH_ALLOWED_REDIRECT_URIS

List of allowed redirect URIs for social authentication.

Example: ['https://auth.example.com'] Default: []

PERMISSIONS

Dictionary that maps permissions to certain views across Djoser.

Examples

{
    'user': ['djoser.permissions.CurrentUserOrAdminOrReadOnly']
}

Defaults

{
    'activation': ['rest_framework.permissions.AllowAny'],
    'password_reset': ['rest_framework.permissions.AllowAny'],
    'password_reset_confirm': ['rest_framework.permissions.AllowAny'],
    'set_password': ['djoser.permissions.CurrentUserOrAdmin'],
    'set_username': ['rest_framework.permissions.IsAuthenticated'],
    'user_create': ['rest_framework.permissions.AllowAny'],
    'user_delete': ['djoser.permissions.CurrentUserOrAdmin'],
    'user': ['djoser.permissions.CurrentUserOrAdminOrReadOnly'],
    'user_list': ['djoser.permissions.CurrentUserOrAdminOrReadOnly'],
    'token_create': ['rest_framework.permissions.AllowAny'],
    'token_destroy': ['rest_framework.permissions.IsAuthenticated'],
}

Base Endpoints

User

Use this endpoint to retrieve/update user.

Default URL: /users/me/ Backward-compatible URL: /me/

Method Request Response
GET

HTTP_200_OK

  • {{ User.USERNAME_FIELD }}
  • {{ User._meta.pk.name }}
  • {{ User.REQUIRED_FIELDS }}
PUT {{ User.REQUIRED_FIELDS }}

HTTP_200_OK

  • {{ User.USERNAME_FIELD }}
  • {{ User._meta.pk.name }}
  • {{ User.REQUIRED_FIELDS }}

User Create

Use this endpoint to register new user. Your user model manager should implement create_user method and have USERNAME_FIELD and REQUIRED_FIELDS fields.

Default URL: /users/ Backward-compatible URL: /users/create/

Method Request Response
POST
  • {{ User.USERNAME_FIELD }}
  • {{ User.REQUIRED_FIELDS }}
  • password

HTTP_201_CREATED

  • {{ User.USERNAME_FIELD }}
  • {{ User._meta.pk.name }}
  • {{ User.REQUIRED_FIELDS }}

User Delete

Use this endpoint to delete authenticated user. By default it will simply verify password provided in current_password, delete the auth token if token based authentication is used and invoke delete for a given User instance. One of ways to customize the delete behavior is to override User.delete.

Default URL: /users/me/

Method Request Response
DELETE
  • current_password

HTTP_204_NO_CONTENT

HTTP_400_BAD_REQUEST

  • current_password

Backward-compatible URL: /users/delete/

Method Request Response
POST
  • current_password

HTTP_204_NO_CONTENT

HTTP_400_BAD_REQUEST

  • current_password

User Activate

Use this endpoint to activate user account. This endpoint is not a URL which will be directly exposed to your users - you should provide site in your frontend application (configured by ACTIVATION_URL) which will send POST request to activate endpoint.

Default URL: /users/confirm/ Backward-compatible URL: /users/activate/

Method Request Response
POST
  • {{ User.USERNAME_FIELD }}
  • token
HTTP_204_NO_CONTENT

User Resend Activation E-mail

Use this endpoint to re-send the activation e-mail. Note that no e-mail would be sent if the user is already active or if they don’t have a usable password. Also if the sending of activation e-mails is disabled in settings, this call will result in HTTP_400_BAD_REQUEST

Default URL: /users/resend/

Method Request Response
POST
  • {{ User.USERNAME_FIELD }}
HTTP_204_NO_CONTENT HTTP_400_BAD_REQUEST

Set Username

Use this endpoint to change user username (USERNAME_FIELD).

Default URL: /users/change_username/ Backward-compatible URL: /{{ User.USERNAME_FIELD }}/

Note

re_new_{{ User.USERNAME_FIELD }} is only required if SET_USERNAME_RETYPE is True

Method Request Response
POST
  • new_{{ User.USERNAME_FIELD }}
  • re_new_{{ User.USERNAME_FIELD }}
  • current_password
HTTP_204_NO_CONTENT

Set Password

Use this endpoint to change user password.

Default URL: /password/

Note

re_new_password is only required if SET_PASSWORD_RETYPE is True

Method Request Response
POST
  • new_password
  • re_new_password
  • current_password
HTTP_204_NO_CONTENT

Reset Password

Use this endpoint to send email to user with password reset link. You have to setup PASSWORD_RESET_CONFIRM_URL.

Default URL: /password/reset/

Note

HTTP_204_NO_CONTENT if PASSWORD_RESET_SHOW_EMAIL_NOT_FOUND is False

Otherwise and if email does not exist in database HTTP_400_BAD_REQUEST

Method Request Response
POST {{ User.USERNAME_FIELD }}
  • HTTP_204_NO_CONTENT
  • HTTP_400_BAD_REQUEST

Reset Password Confirmation

Use this endpoint to finish reset password process. This endpoint is not a URL which will be directly exposed to your users - you should provide site in your frontend application (configured by PASSWORD_RESET_CONFIRM_URL) which will send POST request to reset password confirmation endpoint.

Default URL: /password/reset/confirm/

Note

re_new_password is only required if PASSWORD_RESET_CONFIRM_RETYPE is True

Method Request Response
POST
  • {{ User.USERNAME_FIELD }}
  • token
  • new_password
  • re_new_password
HTTP_204_NO_CONTENT

Token Endpoints

Token Create

Use this endpoint to obtain user authentication token. This endpoint is available only if you are using token based authentication.

Default URL: /token/login/ Backward-compatible URL: /token/create/

Method Request Response
POST
  • {{ User.USERNAME_FIELD }}
  • password

HTTP_200_OK

  • auth_token

Token Destroy

Use this endpoint to logout user (remove user authentication token). This endpoint is available only if you are using token based authentication.

Default URL: /token/logout/ Backward-compatible URL: /token/destroy/

Method Request Response
POST HTTP_204_NO_CONTENT

JWT Endpoints

JWT Create

Use this endpoint to obtain JWT.

Default URL: /jwt/create/

Method Request Response
POST
  • {{ User.USERNAME_FIELD }}
  • password

HTTP_200_OK

  • access
  • refresh

HTTP_400_BAD_REQUEST

  • non_field_errors

JWT Refresh

Use this endpoint to refresh JWT.

Default URL: /jwt/refresh/

Method Request Response
POST
  • refresh

HTTP_200_OK

  • access

HTTP_400_BAD_REQUEST

  • non_field_errors

JWT Verify

Use this endpoint to verify JWT.

Default URL: /jwt/verify/

Method Request Response
POST
  • token

HTTP_200_OK

HTTP_400_BAD_REQUEST

  • non_field_errors

Social Endpoints

Warning

This API is in beta quality - backward compatibility is not guaranteed in future versions and you may come across bugs.

Provider Auth

Using these endpoints you can authenticate with external tools.

The workflow should look like this:

  1. Access the endpoint providing a redirect_uri that would perform the POST action later.
  2. The request would return a JSON containing one key authorization_url. Redirect the user to that URL.
  3. When the user authenticates with the external tool, that tool would redirect them to the redirect_uri you provided with a GET querystring containing two arguments: code and state
  4. From the view that your user got redirected to, issue a POST request to the endpoint with the code and state arguments. You should use application/x-www-form-urlencoded not JSON. The user should be now authenticated in your application.

The list of providers is available at social backend docs. please follow the instructions provided there to configure your backend.

Default URL: /o/{{ provider }}/

Note

  • redirect_uri is provided via GET parameters - not JSON
  • state parameter isn’t always required e.g. in case of OpenID backends
Method Request Response
GET
  • redirect_uri

HTTP_200_OK

  • authorization_url

HTTP_400_BAD_REQUEST

POST
  • code
  • state

HTTP_201_CREATED

  • token

HTTP_400_BAD_REQUEST

  • non_field_errors

Signals

Djoser provides a set of signals that allow you to hook into Djoser user management flow.

user_registered

This signal is sent after successful user registration.

Argument Value
sender sender class
user user instance
request request instance

At this point, user has already been created and saved.

user_activated

This signal is sent after successful user activation.

Argument Value
sender sender class
user user instance
request request instance

At this point, user has already been activated and saved.

Migration Guide

Migrating from 1.3 to 1.4

Due to a lack of maintenance on the django-rest-framework-jwt project, Djoser has switched to using django-rest-framework-simplejwt. This update includes some backwards-incompatible changes:

  1. The response from the JWT Create endpoint includes both an access and refresh token. access is essentially the same as the old token and can be used to authenticate requests. refresh is used to acquire a new access token.

  2. The JWT Refresh endpoint requires the refresh token and returns a new access token.

  3. The JWT Verify endpoint no longer returns token.

  4. django-rest-framework-simplejwt uses Authorization: Bearer <token>. This can be overridden by adding the following to Django Settings:

    SIMPLE_JWT = {
        'AUTH_HEADER_TYPES': ('JWT',),
    }
    

Migrating from 1.1 to 1.2

There is no urgent need to change anything as backward compatibility is retained. That being said we ask you to change usage from old endpoints to new ones for the warm fuzzy feeling of being more RESTful :)

Migrating from 0.x to 1.0

The stable release has introduced a number of backward incompatible changes and purpose of this guide is to allow developer to quickly adapt a given project.

Removal of UserEmailFactoryBase and its subclasses

As mentioned in Emails page since 1.0 email support has been removed from Djoser and it is advised to use django-templated-mail for use cases which were previously handled by djoser email support. You can find out more about it in the project documentation. Keep in mind that DOMAIN and SITE_NAME settings have also been moved to django-templated-mail as described in settings page.

Base URLs are no longer included with other URLs

Previously djoser.urls.base were bundled with djoser.urls.authtoken, however in some cases developer might not need them and therefore if base URLs are needed it is now necessary to explicitly include them, e.g.:

urlpatterns = [
    (...),
    url(r'^auth/', include('djoser.urls')),
    url(r'^auth/', include('djoser.urls.authtoken')),
]

Dropped support for Django < 1.10

Support for Django 1.8 and 1.9 has been dropped in Django REST Framework 3.7 and hence there was no reason to keep it in djoser. It is recommended to upgrade to Django 1.11, since 1.10 will EOL in December 2017. Django Deprecation Timeline and Django Release Notes are very helpful in the process.

Some View class names and URLs has been updated

Also please note that for sake of consistency all URLs now end with a trailing slash. The trailing slash is optional to ensure compatibility with frontend tools that strip the trailing slash (eg Google’s Chrome browser and Angular framework).

View class names:

  • RegistrationView has been renamed to UserCreateView
  • LoginView has been renamed to TokenCreateView
  • LogoutView has been renamed to TokenDestroyView

Base URLs:

  • register/ has been renamed to users/create/
  • register URL name has been renamed to user-create
  • activate/ has been renamed to users/activate/
  • activate URL name has been renamed to user-activate

Token Based Authentication URLs:

  • login/ has been renamed to token/create/
  • login URL name has been renamed to token-create
  • logout/ has been renamed to token/destroy/
  • logout URL name has been renamed to token-destroy

Emails

Explicit email support has been removed from djoser in 1.0.0. It didn’t make sense to handle such responsibility in a package, which should simply provide an implementation of common authentication-related REST endpoints.

Email support is now handled with the django-templated-mail package.

Email classes can be overridden using EMAIL setting

Adjustment

If you need to customize any serializer behaviour you can use the DJOSER['SERIALIZERS'] setting to use your own serializer classes in the built-in views. Or if you need to completely change the default djoser behaviour, you can always override djoser views with your own custom ones.

Define custom urls instead of reusing djoser.urls:

urlpatterns = patterns('',
    (...),
    url(r'^register/$', views.CustomRegistrationView.as_view()),
)

Define custom view/serializer (inherit from one of djoser class) and override necessary method/field:

class CustomRegistrationView(djoser.views.RegistrationView):

    def send_activation_email(self, *args, **kwargs):
        your_custom_email_sender(*args, **kwargs)

You could check djoser API in source code:

Examples

Early detecting invalid password reset tokens

When there is need to check if password reset token is still valid without actually resetting the password it is possible to approach the problem like so:

from django.contrib.auth.tokens import default_token_generator
from rest_framework import generics, permissions, status
from rest_framework.response import Response

from djoser import serializers


class PasswordTokenCheckView(generics.CreateAPIView):
    permission_classes = (
        permissions.AllowAny,
    )
    token_generator = default_token_generator
    serializer_class = serializers.UidAndTokenSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_200_OK, headers=headers)

Indices and tables