JSON Web Token Authentication support for Django REST Framework

Overview

REST framework JWT Auth


Notice

This project is currently unmaintained. Check #484 for more details and suggested alternatives.


build-status-image pypi-version

JSON Web Token Authentication support for Django REST Framework

Full documentation for the project is available at docs.

Overview

This package provides JSON Web Token Authentication support for Django REST framework.

If you want to know more about JWT, check out the following resources:

Requirements

  • Python (2.7, 3.3, 3.4, 3.5, 3.6)
  • Django (1.8, 1.9, 1.10, 1.11)
  • Django REST Framework (3.1, 3.2, 3.3, 3.4, 3.5, 3.6)

Installation

Install using pip...

$ pip install djangorestframework-jwt

Documentation & Support

Full documentation for the project is available at docs.

You may also want to follow the author on Twitter.

Comments
  • Add refresh token feature

    Add refresh token feature

    Added an optional endpoint that can refresh a token. This can be useful for a webapp to try to keep a user logged in without having to re-enter their password constantly. Got the idea from this post https://auth0.com/blog/2014/01/27/ten-things-you-should-know-about-tokens-and-cookies/

    Basically, if JWT_ALLOW_TOKEN_RENEWAL is True, then an extra field orig_iat (stands for original issue at time) is stored on the returned JWT token. You can then pass the token to the RefreshJSONWebToken view, and if orig_iat hasn't yet expired, you get a token with a refreshed expiration time (but with the same orig_iat, so you can only do refreshes up to some time limit, specified in JWT_TOKEN_RENEWAL_LIMIT). Getting a brand new token (by passing in username/password) will return a completely new orig_iat though.

    I also added a new handler, jwt_get_user_id_from_payload, that lets you specify how the user_id field is stored. Since it's possible for the custom payload handler to change how the user id is stored, it seems to make sense to have a way to retrieve it too.

    Feedback welcome (there are some things that could probably be cleaned up). I didn't add tests yet but if there is interest in this PR I will write some (I did write a number of tests in my application that uses this, so I am reasonably confident it works).

    opened by alvinchow86 32
  • request.user shows AnonymousUser in middleware

    request.user shows AnonymousUser in middleware

    I'm not sure if this is an issue or just because of the implementation, but I was using middleware to log user_id against records being edited, and I couldn't get request.user at the middleware level (and so of course request.user.is_authorized() returned False).

    The middleware was the last one on the list, and authorization was working (I would get a 403 requesting assets without my token header). I tried putting 'rest_framework_jwt.authentication.JSONWebTokenAuthentication' at the top of DEFAULT_AUTHENTICATION_CLASSES, and also making it the only item in the tuple; neither worked.

    I've managed to work around my issue by accessing the header and using the tools directly in the app to retrieve the user; essentially I copied chunks of your code into my middleware, but I thought you should know :)

    If you're interested, here's the middleware:

    from django.db.models import signals
    from django.utils.functional import curry
    from django.utils import timezone
    from threading import local
    
    import jwt
    from rest_framework.authentication import get_authorization_header
    from rest_framework_jwt.settings import api_settings
    from django.conf import settings
    try:
        from django.contrib.auth import get_user_model
    except ImportError:  # Django < 1.5
        from django.contrib.auth.models import User
    else:
        User = get_user_model()
    
    _user = local()
    
    class AuditMiddleware(object):
        def process_request(self, request):
            if not request.method in ('GET', 'HEAD', 'OPTIONS', 'TRACE'):
                if hasattr(request, 'user') and request.user.is_authenticated():
                    user = request.user
                else:
                    user = self.get_user_from_auth_header(request)
                    if user is not None:
                        request.user = user
    
                _user.value = user
    
                mark_whodid = curry(self.mark_whodid, _user.value)
                signals.pre_save.connect(mark_whodid,  dispatch_uid = (self.__class__, request,), weak = False)
    
        def process_response(self, request, response):
            signals.pre_save.disconnect(dispatch_uid =  (self.__class__, request,))
            return response
    
        def mark_whodid(self, user, sender, instance, **kwargs):
            # user logging here
    
        def get_user_from_auth_header(self, request):
            try:
                auth_keyword, token = get_authorization_header(request).split()
                jwt_header, claims, signature = token.split('.')
    
                try:
                    payload = api_settings.JWT_DECODE_HANDLER(token)
                    try:
                        user_id = api_settings.JWT_PAYLOAD_GET_USER_ID_HANDLER(payload)
    
                        if user_id:
                            user = User.objects.get(pk=user_id, is_active=True)
                            return user
                        else:
                            msg = 'Invalid payload'
                            return None
                    except User.DoesNotExist:
                        msg = 'Invalid signature'
                        return None
    
                except jwt.ExpiredSignature:
                    msg = 'Signature has expired.'
                    return None
                except jwt.DecodeError:
                    msg = 'Error decoding signature.'
                    return None
            except ValueError:
                return None
    
    opened by marcelkornblum 30
  • `NotImplementedError` on accessing `request.DATA`

    `NotImplementedError` on accessing `request.DATA`

    From django-rest-framework v3.2, any attempts to access request.DATA will raise a NotImplementedError with the following message:

    request.DATA has been deprecated in favor of request.data since version 3.0, and has been fully removed as of version 3.2.

    You can see the change commit here. The error originates here in views.py.

    Note that the request.data property appears to have been added in django-rest-framework v3, so simply changing request.DATA to request.data may make this package incompatible with earlier versions.

    opened by ghost 20
  • Add support for Django 1.10 and Django REST Framework 3.4

    Add support for Django 1.10 and Django REST Framework 3.4

    This branch takes a slightly different approach to 1.10/3.4 support than #252. It includes:

    • Updated documentation indicating change in support.
    • Add 1.10 and 3.4 to the Travis build matrix and tox file.
    • Consolidates the test views into tests/urls.py. 1.10 wasn't working with urlpatterns in the test_views and test_authentication files.
    • Tests the is_active behavior for the pre-1.10 ModelBackend and uses the new AllowAllUsersModelBackend to test the similar behavior for 1.10.
    • Turns on verbose for tox execution to show what is skipped for Travis builds.

    There is one oddity in this branch that I can't really explain well. test_jwt_login_custom_response_json did a check for the username with:

    self.assertEqual(response.data['user'], self.username)
    

    That data did not exist under 1.10 and I don't understand why. Someone with a bit more history with the project might want to check if that's ok or a behavioral regression that needs to be fixed first.

    opened by mblayman 16
  • Long running refresh tokens

    Long running refresh tokens

    related to #117 and #94

    But change the way we obtain a new JWT. Compare to #94, now the implementation try to be more compliant with https://auth0.com/docs/refresh-token

    The delegation endpoint is a POST, with the following body.

    {
      "client_id":       "YOUR_CLIENT_ID",
       "grant_type":      "urn:ietf:params:oauth:grant-type:jwt-bearer",
       "refresh_token":   "YOUR_REFRESH_TOKEN",
       "api_type":        "app"
    }
    

    instead of being a POST + empty body + the refresh token passed in Authorization header.

    /cc @fxdgear

    TODO before merging:

    • [ ] provide a squashed migration
    opened by ticosax 16
  • Wrong behavior if a field is empty

    Wrong behavior if a field is empty

    If authenticating using a recent JWT, the request fails with

    {"detail": "Invalid payload"}
    

    in case a field is empty (tested here with user account that was lacking an email address)

    opened by arnuschky 13
  • Allow using a cookie as a transport for the token

    Allow using a cookie as a transport for the token

    A new configuration 'JWT_AUTH_COOKIE' has been added. If it set to None (the default), everything works the same.

    It can be set to a string to use as the name of the cookie that can be used to carry the token. Note the 'Authorization' header is still accepted as the primary method, but it falls back to the designated cookie if present.

    When a token is requested and 'JWT_AUTH_COOKIE' is set, the response will set the given cookie with the token string.

    Fix #120

    opened by moises-silva 11
  • Refresh token not working

    Refresh token not working

    I'm using all the default settings (including the default URLS), and using CURL to refresh the token but I get the following error:

    {"non_field_errors":["orig_iat field is required."]}

    Any idea why this error is occurring?

    opened by mtmithani 11
  • Added a JWT verification view

    Added a JWT verification view

    This PR adds a verification view: verify_jwt_token, which checks if a JWT POSTed to it is valid and that the user exists.

    Much of the functionality is the same as the existing refresh view and serializer. I abstracted out the majority of the shared serializer logic to maximise DRYness. There are several other ways this could be implemented, however.

    I added tests for the new view and moved a test which was more relevant to this functionality from the refresh view tests.

    Suggestions for improvements welcome! If the serializer implementation is ok, it could probably use some unit tests.

    opened by Jwpe 11
  • Fix refresh tokens

    Fix refresh tokens

    Trying to get an new token, with an 'expired' token results in an signature error. The token is decoded with verification of 'exp' claim. Only the orig_iat claim should be verified in this case.

    Problem is the JWT_DECODE_HANDLER does not have an option to disable exp verification. Changing the default handler would be an backwards incompatible change... not sure how you guys would want to handle that. So in this pull it has it's own call to jwt.encode...

    Fixes #249

    opened by jor-rit 9
  • Need user id with token

    Need user id with token

    I am stuck with the JWT, can any one tell me how can I get user ID along with token.

    My url.py :

    from webservices import views
    
    router = routers.DefaultRouter()
    router.register(r'api/users', views.UserViewSet)
    
    
    urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^api/login/', obtain_jwt_token),
    ]
    
    opened by aashishsoni-zz 9
  • Cookie not removed in request when response is 401

    Cookie not removed in request when response is 401

    I'm using JWT in a httpOnly cookie and allowing multiple logins on the system. If I have 2 sessions opened with the same user (different JWT tokens) and if one of them logs out I reset all JWT tokens by changing the user's UUID. I also delete that session's cookie by means of:

            response = HttpResponse()
            response.delete_cookie("cookie.jwt",path="/")
    

    This logs out both browser sessions and that's OK, but the browser session in which I DID NOT explicitly log out keeps an invalid cookie in the browser and I can't get rid of it via javascript because its httpOnly (I want it to stay that way). All further requests to the server return as a 401 and I can't seem to change the response to add a "delete_cookie".

    Two questions:

    1. Why not always delete the cookie JWT_AUTH_COOKIE from the response if an exception is raised by JWT?

    2. How can I work around this issue?

    Thanks!

    opened by pedroflying 0
  • Can we use allauth only for the things, where we can get involved with email verification, and jwt for others purposes like login/get api request/ post api requests....????

    Can we use allauth only for the things, where we can get involved with email verification, and jwt for others purposes like login/get api request/ post api requests....????

    I am very confused about using allauth/jwt? I need email verification for account activation/deletion and many other things but i also need jwt token like thing to secure get/post apis.... What can i do???? I am beginner to django....!!!!!!! Sorry if my english is poor....!!!

    opened by SohaibShafiq1 0
  • Unreachable code when user is_active is False in.

    Unreachable code when user is_active is False in.

    https://github.com/jpadilla/django-rest-framework-jwt/blob/4021e0bd46eed8ca7dd0ea9337e2606951cb55fb/rest_framework_jwt/serializers.py#L53

    When using the default ModelBackend in django settings activated, the authenticate method in django.contrib.auth.backends.ModelBackend has the user_can_authenticate method. In our case user.is_active is False and as a result the whole authenticate method in this file returns None. As a result in line 53 there is a check if the user is_active but it is unreachable in this point and we render the wrong message which is in line 64.

    opened by tzimos 1
  • DeprecationWarning: The following fields will be removed in the future: `email` and `user_id`.

    DeprecationWarning: The following fields will be removed in the future: `email` and `user_id`.

    Hello,

    I am using email instead of username for authentication. So my custom user model does not have username field. My code is based on this

    Now I am setting up jwt authentication and I receive the following warning:

    rest_framework_jwt/utils.py:39: DeprecationWarning: The following fields will be removed in the future: `email` and `user_id`.
        DeprecationWarning
    

    Is there something that I can do to overcome this (other than using username, which will not be an option)

    thanks!

    opened by ajendrex 1
  • Status

    Status

    Hello there,

    For a long time now I've honestly thought I'd have the time and energy to come back and work on this project, and I think I still don't. I've not worked on any project recently needing it, which makes it harder to find time to come back.

    At some point I also noticed I no longer liked how the project had evolved and that it deserved a fair redesign and there are a few fundamental changes required. Now I'm certain that I wouldn't be able to work on this with the care required for a major version bump.

    I'm definitely not proud at how long it has taken me to make this or any update, I recognize that and I'm sorry for not having spoken out sooner.

    There's two efforts/projects that I'd like to point out to:

    Fork: https://github.com/Styria-Digital/django-rest-framework-jwt Drop-in updated replacement fork. I'm willing to transfer repo, pypi, etc, to keep this going.

    Alternative: https://github.com/davesque/django-rest-framework-simplejwt Many of the changes that I've wanted to work on are already done here. This is what I would probably use today.

    Learned quite a few things from this. Thanks to everyone, including past collaborators and contributors. ❤️

    Update:

    I've transferred the repository from @GetBlimp. Neither @GetBlimp nor @gcollazo are involved with this project anymore.

    discussion 
    opened by jpadilla 12
  • How to use this library by only using Http Only Cookie?

    How to use this library by only using Http Only Cookie?

    After using JWT token in un unsafe way for a little over an year I've finally decided that I would like to fix my current setup.

    I read everywhere that is not good to save a JWT token in the local client and that is best to use Http Only Cookie.

    I'm now trying to use JWT_AUTH_COOKIE in order to create an Http Only Cookie. I'm getting the Cookie correctly returned by the server when using getToken API. What I'm wondering now, is how I can refresh the token.

    What happens when I call refreshToken I get the following response:

    {"token":["This field is required."]}
    

    True, I'm not sending any token in the request's HEADER and that is what I want since the client isn't supposed to keep it saved anywhere.

    And that is where I'm getting confused:

    If i'm not wrong from now on every request the client does to the server, the cookie should be added to the request.

    Shouldn't the server check the cookie after it sees that no token has been passed in the Header?

    opened by pinkynrg 1
Releases(1.11.0)
  • 1.11.0(Jun 23, 2017)

    Changelog

    Added

    • Test on Django 1.11 #325 by @orf
    • Allow jtw_payload_handler to work with User models that don't have an Email field #268 by @shanx

    Changes

    • Bump up PyJWT to 1.5.2 636539eb9452c415bbd53094186ee45d56473422
    • Don't require the 'token' key to override jwt_response_payload_handler #323 by @brianrower

    Docs

    • Fix typo in jwt_get_secret_key doc #343 by @blueyed
    Source code(tar.gz)
    Source code(zip)
  • 1.10.0(Mar 22, 2017)

    Changelog

    Added

    • Update of django, drf, python version handling in tox.ini #262 by @angvp
    • Allow using a cookie as a transport for the token #275 by @moises-silva | Docs
    • Allow secret to be kept on user model #310 by @jacoor | Docs

    Changes

    • Replace login with log in when used as a verb #295 by @rriehle

    Docs

    • Minor typo and formatting correction index.md #293 by @matthewhegarty
    • Minor fix: formatting for phrase brand-new #301 by @sumittada
    Source code(tar.gz)
    Source code(zip)
  • 1.9.0(Dec 1, 2016)

  • 1.8.0(Apr 3, 2016)

    This release drops official support for Django REST Framework version 2.x as well as end of life versions of Django.

    Support versions are now Django 1.8 and 1.9 with Django REST Framework 3.x.

    We also add support for custom user models with Django 1.8's UUIDField as primary key.

    Source code(tar.gz)
    Source code(zip)
  • 1.7.1(Aug 18, 2015)

  • 1.7.0(Aug 17, 2015)

    Changelog

    Changed

    • Upgrade PyJWT to v1.4.0. 9a43d6303acfdd0724468cbb95a72bde03f38bff
    • Rely on get_by_natural_key instead of fetching by user's id. a3b4d44d2fc34d7752793ccbade2684707bf41da
    • Include optional orig_iat in jwt_payload_handler. eb208893a223686efbf52ef81c37b915cc2edc00
    • Remove throttle override in JSONWebTokenAPIView. #138

    Fixed

    • Use correct input type for password form field. Fixes #133
    • Use USERNAME_FIELD in utils.jwt_payload_handler. Fixes #128

    Added

    • Add support for DRF 3.2
    • Add JWT_PAYLOAD_GET_USERNAME_HANDLER setting. a3b4d44d2fc34d7752793ccbade2684707bf41da
    • Add username to jwt_payload_handler. a3b4d44d2fc34d7752793ccbade2684707bf41da
    • Add deprecation warning to jwt_payload_handler. a3b4d44d2fc34d7752793ccbade2684707bf41da
    • Add deprecation warning to jwt_get_user_id_from_payload_handler. a3b4d44d2fc34d7752793ccbade2684707bf41da
    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Jun 12, 2015)

    Changelog

    Changed

    • Speed up tests. #108
    • Bump up PyJWT version to v1.3.0. 54048f751ec00d73abf110a231fca8f2340156ef
    • Drop support for Python 3.2. dfb320885e53b8ce988d3f2c6d4535488354b5d6
    • Added the ability to use custom renderers. #121

    Fixed

    • Verify now does not refresh token. #109
    • Fixed testing DRF 2 with Django 1.8. #118
    • Run tests only against latest DRF versions. #122

    Added

    • Add request to serializers' context. #119

    tgif

    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(Apr 28, 2015)

    Changelog

    Fixed

    • Catch InvalidTokenError and raise exception #100
    • Fixed verify_expiration no longer supported by PyJWT #103
    • Add Python 3.2 to tox tests #95
    • Propagate request arg in all the doc strings #90
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Mar 19, 2015)

  • 1.3.0(Mar 7, 2015)

    • Update en_US PO file by @migonzalvar. #83
    • Allow subclassing JSONWebTokenAuthentication by @cancan101. #80
    • Allow setting audience and issuer by @cancan101. #77
    • Added a JWT verification view by @Jwpe. #75
    • Support HyperlinkedModelSerializer by @semente. #73
    • Added JWT TestCase Class and Client by @davideme. #72

    Thanks to all that contributed to make this release happen.

    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jan 24, 2015)

    • Changed potentially misleading error message by @skolsuper. #59
    • Added JWT_RESPONSE_PAYLOAD_HANDLER by @erichonkanen. #62
    • Fixed user import problem for custom users by @cenkbircanoglu. #70
    • Added translation utils by @migonzalvar. #68

    Thanks to all that contributed to make this release happen.

    Thank You

    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Dec 11, 2014)

  • 1.1.0(Dec 3, 2014)

  • 1.0.2(Oct 23, 2014)

  • 1.0.1(Sep 3, 2014)

  • 1.0.0(Aug 30, 2014)

    I've just released v1.0.0 to PyPI. This release should not introduce any breaking changes but made sense the package's major version was correctly incremented.

    This introduces one new feature: Refresh Tokens. This feature was introduced in PR #23 by @alvinchow86 and also introduces some fixes by @liamlin.

    A typical use case for might be a web app where you'd like to keep the user "logged in" the site without having to re-enter their password, or get kicked out by surprise before their token expired. Imagine they had a 1-hour token and are just at the last minute while they're still doing something. With mobile you could perhaps store the username/password to get a new token, but this is not a great idea in a browser. Each time the user loads the page, you can check if there is an existing non-expired token and if it's close to being expired, refresh it to extend their session. In other words, if a user is actively using your site, they can keep their "session" alive.

    This release also introduces a new setting: JWT_AUTH_HEADER_PREFIX. This allows you to modify the Authorization header value prefix that is required to be sent together with the token. The default value is JWT. This decision was introduced in PR #4 to allow using both this package and OAuth2 in DRF.

    Another common value used for tokens and Authorization headers is Bearer.

    Thanks to everyone that helped make this release happen. You're awesome!

    Source code(tar.gz)
    Source code(zip)
Owner
José Padilla
@auth0 + @filepreviews
José Padilla
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 1, 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

Jazzband 3.2k Dec 29, 2022
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

Jazzband 3.2k Dec 28, 2022
CheckList-Api - Created with django rest framework and JWT(Json Web Tokens for Authentication)

CheckList Api created with django rest framework and JWT(Json Web Tokens for Aut

shantanu nimkar 1 Jan 24, 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 3, 2023
Django CAS 1.0/2.0/3.0 client authentication library, support Django 2.0, 2.1, 2.2, 3.0 and Python 3.5+

django-cas-ng django-cas-ng is Django CAS (Central Authentication Service) 1.0/2.0/3.0 client library to support SSO (Single Sign On) and Single Logou

django-cas-ng 347 Dec 18, 2022
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 3, 2023
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 3, 2023
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
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 1, 2023
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 3, 2023
Django-react-firebase-auth - A web app showcasing OAuth2.0 + OpenID Connect using Firebase, Django-Rest-Framework and React

Demo app to show Django Rest Framework working with Firebase for authentication

Teshank Raut 6 Oct 13, 2022
User-related REST API based on the awesome Django REST Framework

Django REST Registration User registration REST API, based on Django REST Framework. Documentation Full documentation for the project is available at

Andrzej Pragacz 399 Jan 3, 2023
python-social-auth and oauth2 support for django-rest-framework

Django REST Framework Social OAuth2 This module provides OAuth2 social authentication support for applications in Django REST Framework. The aim of th

null 1k Dec 22, 2022
python-social-auth and oauth2 support for django-rest-framework

Django REST Framework Social OAuth2 This module provides OAuth2 social authentication support for applications in Django REST Framework. The aim of th

null 1k Dec 22, 2022
REST implementation of Django authentication system.

djoser REST implementation of Django authentication system. djoser library provides a set of Django Rest Framework views to handle basic actions such

Sunscrapers 2.2k Jan 1, 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 878 Jan 4, 2023
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 9, 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