[Fixed]-Override the authToken views in Django Rest

10๐Ÿ‘

From docs.

First that you need is to extend the ObtainAuthToken class.

# views.py

from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from rest_framework.response import Response

class CustomAuthToken(ObtainAuthToken):

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data,
                                       context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({
            'token': token.key,
            'user_id': user.pk,
            'email': user.email
        })

And after this add the CustomAuthToken class to your urls.py like view

# urls.py
from django.urls import path
from . import views

urlpatterns += [
    path(r'api-token-auth/', views.CustomAuthToken.as_view())
]
๐Ÿ‘คDruta Ruslan

4๐Ÿ‘

You should extend your CustomClass from AuthToken, the route default url to your CustomClass:

from rest_framework_jwt.views import ObtainJSONWebToken

class JSONWebTokenAPIOverride(ObtainJSONWebToken):
    """
    Override JWT
    """
    def post(self, request):
        # Do whatever you want

Then in your urls.py:

url(
    r'^api-auth$',
    cache_page(0)(views.JSONWebTokenAPIOverride.as_view())
)

I hope it helps

๐Ÿ‘คMoe Far

1๐Ÿ‘

I wanted to override some default CRSF functionality and used the following approach:

from rest_framework.authentication import SessionAuthentication

class SessionCsrfExemptAuthentication(SessionAuthentication):

    def enforce_csrf(self, request):
        # Do not perform a csrf check
        return False

Then in my settings file I referenced it in the following way:

'DEFAULT_AUTHENTICATION_CLASSES': (
    'myapp.utils.authenticate.SessionCsrfExemptAuthentication',
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    'oauth2_provider.ext.rest_framework.OAuth2Authentication',
    'rest_framework_social_oauth2.authentication.SocialAuthentication',
),

This allowed me to import the existing functionality, override it and reference it in the settings file. I think you can use a similar approach here.

๐Ÿ‘คdjq

0๐Ÿ‘

I use the option JWT_RESPONSE_PAYLOAD_HANDLER.
In the response I include the token, expiration timestamp and the user.

In settings.py add:

JWT_AUTH = {
        ...
        'JWT_RESPONSE_PAYLOAD_HANDLER':'<app_name>.functions.custom_jwt_response',
}

Then in functions.py add the following

def custom_jwt_response(token, user=None, request=None):

    import jwt
    jwt = jwt.decode(token, verify=False)

    return {
        'token': token,
        'token_exp': jwt['exp'],
        'user': UserSerializer(user, context={'request': request}).data
    }
๐Ÿ‘คSlipstream

0๐Ÿ‘

The answers here are good but in my opinion they donโ€™t make full use of inheritance. When we inherit a class, we shouldnโ€™t just try to reinvent the wheel and instead make use of the super() keyword. Here is my code example, where I want to turn the username argument into lowercase before performing the authentication request:

class GetAuthToken(ObtainAuthToken):
   """
   Override Django's ObtainAuthToken to provide custom way of authenticating user for token
   """
   def post(self, request, *args, **kwargs):
      #-- turn username to lowercase
      if ('username' in request.data):
         request.data['username'] = request.data['username'].lower()

      #-- perform normal function
      return super().post(request, *args, **kwargs)

Leave a comment