Skip to content

REST implementation of Django authentication system.

License

Notifications You must be signed in to change notification settings

Sreemanth/djoser

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

djoser

Build Status Coverage Status

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.

We use token based authentication. The concept is simple - first of all, users obtain a token by providing their credentials (e.g. username, password) during logging in. Once the token is obtained users can offer it in order to retrieve a specific resource. In other words, users have been granted access to a specific resource for a fixed time period. Django REST framework supports token based authentication but you might be interested in other authentication mechanisms like OAuth or session-based authentication.

Developed by SUNSCRAPERS with passion & patience.

Available endpoints:

  • /me
  • /register
  • /login
  • /logout
  • /activate
  • /{{ User.USERNAME_FIELD }}
  • /password
  • /password/reset
  • /password/reset/confirm

Supported Python versions:

  • Python 2.7
  • Python 3.4

Supported Django versions:

  • Django 1.5
  • Django 1.6
  • Django 1.7

Installation

Use pip:

$ pip install djoser

Usage

Configure INSTALLED_APPS:

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

Configure urls.py:

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

Use TokenAuthentication as default Django Rest Framework authentication strategy:

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

Optionally add DJOSER settings:

DJOSER = {
    'DOMAIN': 'frontend.com',
    'SITE_NAME': 'Frontend',
    'PASSWORD_RESET_CONFIRM_URL': '#/password/reset/confirm/{uid}/{token}',
    'ACTIVATION_URL': '#/activate/{uid}/{token}',
    'LOGIN_AFTER_ACTIVATION': True,
    'SEND_ACTIVATION_EMAIL': True,
}

Check "Settings" section for more info.

Endpoints

User

Use this endpoint to retrieve/update user.

GET

URL: /me

Retrieve user.

  • response

    • status: HTTP_200_OK (success)

    • data:

      {{ User.USERNAME_FIELD }}

      {{ User.REQUIRED_FIELDS }}

PUT

URL: /me

Update user.

  • request

    • data:

      {{ User.REQUIRED_FIELDS }}

  • response

    • status: HTTP_200_OK (success)

    • data:

      {{ User.USERNAME_FIELD }}

      {{ User.REQUIRED_FIELDS }}

Register

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

If LOGIN_AFTER_ACTIVATION is True, you will receive authentication token within response.

POST

URL: /register

  • request

    • data:

      {{ User.USERNAME_FIELD }}

      {{ User.REQUIRED_FIELDS }}

      password

  • response

    • status: HTTP_201_CREATED (success)

    • data:

      {{ User.USERNAME_FIELD }}

      {{ User.REQUIRED_FIELDS }}

      auth_token (if LOGIN_AFTER_ACTIVATION is True)

Login

Use this endpoint to obtain user authentication token.

POST

URL: /login

  • request

    • data:

      {{ User.USERNAME_FIELD }}

      password

  • response

    • status: HTTP_200_OK (success)

    • data:

      auth_token

Logout

Use this endpoint to logout user (remove user authentication token).

POST

URL: /logout

  • response

    • status: HTTP_200_OK (success)

Activate

Use this endpoint to activate user account.

POST

URL: /activate

  • request

    • data:

      uid

      token

  • response

    • status: HTTP_200_OK (success)

    • data:

      auth_token (if LOGIN_AFTER_ACTIVATION is True)

Set username

Use this endpoint to change user username (USERNAME_FIELD).

POST

URL: /{{ User.USERNAME_FIELD }}

  • request

    • data:

      new_{{ User.USERNAME_FIELD }}

      re_new_{{ User.USERNAME_FIELD }} (if SET_USERNAME_RETYPE is True)

      current_password

  • response

    • status: HTTP_200_OK (success)

Set password

Use this endpoint to change user password.

POST

URL: /password

  • request

    • data:

      new_password

      re_new_password (if SET_PASSWORD_RETYPE is True)

      current_password

  • response

    • status: HTTP_200_OK (success)

Reset password

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

POST

URL: /password/reset

  • request

    • data:

      email

  • response

    • status: HTTP_200_OK (success)

Reset password confirmation

Use this endpoint to finish reset password process.

POST

URL: /password/reset/confirm

  • request

    • data:

      uid

      token

      new_password

      re_new_password (if PASSWORD_RESET_CONFIRM_RETYPE is True)

  • response

    • status: HTTP_200_OK (success)

Settings

LOGIN_AFTER_REGISTRATION

If True, register endpoint will return auth_token within response.

Default: False

DOMAIN

Domain of your frontend app.

Required: True

SITE_NAME

Name of your frontend app.

Required: True

PASSWORD_RESET_CONFIRM_URL

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

Required: True

SEND_ACTIVATION_EMAIL

If True, register endpoint will send activation 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}.

Required: True

LOGIN_AFTER_ACTIVATION

If True, activate endpoint will return auth_token within response.

Default: False

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

Emails

There are few email templates which you may want to override:

  • activation_email_body.txt
  • activation_email_subject.txt
  • password_reset_email_body.txt
  • password_reset_email_subject.txt

All of them have following context:

  • user
  • domain
  • site_name
  • url
  • uid
  • token
  • protocol

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/register --data 'username=djoser&password=djoser'

    {"email": "", "username": "djoser"}

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

  • Let's access user's details:

    $ curl -X GET http://127.0.0.1:8088/auth/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/login --data 'username=djoser&password=djoser'

    {"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 -X GET http://127.0.0.1:8088/auth/me

    {"detail": "Authentication credentials were not provided."}

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

    $ curl -X GET http://127.0.0.1:8088/auth/me -H 'Authorization: Token b704c9fc3655635646356ac2950269f352ea1139'

    {"email": "", "username": "djoser"}

    Yay, it works!

  • Now let's log out:

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

    And try access user profile again:

    $ curl -X GET http://127.0.0.1:8088/auth/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.

Customization

If you need to override some djoser behaviour, you could define your custom view/serializer.

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_email(self, *args, **kwargs):
        your_custom_email_sender(*args, **kwargs)

You could check djoser API in source code:

Development

To start developing on djoser, clone the repository:

$ git clone git@github.com:sunscrapers/djoser.git

In order to run the tests create virtualenv, go to repo directory and then:

$ pip install -r requirements-test.txt

$ cd testproject

$ ./manage.py migrate

$ ./manage.py test

Similar projects

List of projects related to Django, REST and authentication:

About

REST implementation of Django authentication system.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%