Skip to content

drf-rest-auth

Bug
# django-rest-auth (deprecate)
REST_USE_JWT = True  # Enable JWT if needed
Success
# dj-rest-auth
REST_AUTH = {
    ...
    'USE_JWT': True,
}
dj_rest_auth (jwt) refresh token is empty when login
REST_AUTH = {
    ...
    'JWT_AUTH_HTTPONLY':False
} 
settings.py
ACCOUNT_AUTHENTICATION_METHOD = 'EMAIL'
# ACCOUNT_AUTHENTICATION_METHOD = 'email'
# ACCOUNT_AUTHENTICATION_METHOD = 'username'

Importing views

Note
from dj_rest_auth.views import (
    LoginView,
    LogoutView,
    PasswordChangeView,
    PasswordResetView,
    PasswordResetConfirmView,
    UserDetailsView,
    TokenVerifyView,
    TokenRefreshView,
)

from dj_rest_auth.registration.views import (
    RegisterView,
    VerifyEmailView,
    ResendEmailVerificationView,
)
from django.urls import path, include

urlpatterns = [
    path('dj-rest-auth/login/', LoginView.as_view(), name='login'),
    path('dj-rest-auth/logout/', LogoutView.as_view(), name='logout'),
    path('dj-rest-auth/password/change/', PasswordChangeView.as_view(), name='password_change'),
    path('dj-rest-auth/password/reset/', PasswordResetView.as_view(), name='password_reset'),
    path('dj-rest-auth/password/reset/confirm/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('dj-rest-auth/user/', UserDetailsView.as_view(), name='user_details'),
    path('dj-rest-auth/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
    path('dj-rest-auth/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),

    path('dj-rest-auth/registration/', RegisterView.as_view(), name='register'),
    path('dj-rest-auth/registration/verify-email/', VerifyEmailView.as_view(), name='verify_email'),
    path('dj-rest-auth/registration/resend-email/', ResendEmailVerificationView.as_view(), name='resend_email'),
]
from django.contrib import admin
from django.urls import path, include
from dj_rest_auth.views import (
    LoginView,
    LogoutView,
    PasswordChangeView,
    PasswordResetView,
    PasswordResetConfirmView,
    UserDetailsView,
    TokenVerifyView,
    TokenRefreshView,
)
from dj_rest_auth.registration.views import (
    RegisterView,
    VerifyEmailView,
    ResendEmailVerificationView,
)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('dj-rest-auth/login/', LoginView.as_view(), name='login'),
    path('dj-rest-auth/logout/', LogoutView.as_view(), name='logout'),
    path('dj-rest-auth/password/change/', PasswordChangeView.as_view(), name='password_change'),
    path('dj-rest-auth/password/reset/', PasswordResetView.as_view(), name='password_reset'),
    path('dj-rest-auth/password/reset/confirm/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('dj-rest-auth/user/', UserDetailsView.as_view(), name='user_details'),
    path('dj-rest-auth/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
    path('dj-rest-auth/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),

    path('dj-rest-auth/registration/', RegisterView.as_view(), name='register'),
    path('dj-rest-auth/registration/verify-email/', VerifyEmailView.as_view(), name='verify_email'),
    path('dj-rest-auth/registration/resend-email/', ResendEmailVerificationView.as_view(), name='resend_email'),
]

Using dj-rest-auth standalone

No, you do not necessarily need to use django-allauth to use dj-rest-auth. However, dj-rest-auth can integrate with django-allauth to provide additional features, especially for user registration and social authentication. If you only need basic authentication (login, logout, password reset, etc.), you can use dj-rest-auth without django-allauth.

Here are the steps to use dj-rest-auth without django-allauth:

Step 1: Install Required Packages

First, install dj-rest-auth and its dependencies:

pip install dj-rest-auth

Step 2: Add to Installed Apps

Add the required applications to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    ...
    'dj_rest_auth',
    'rest_framework',
    ...
]

Step 3: Configure REST Framework

Add rest_framework settings in settings.py:

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

Step 4: Update URLs

Add the dj-rest-auth URLs to your urls.py:

from django.urls import path, include

urlpatterns = [
    ...
    path('api/auth/', include('dj_rest_auth.urls')),
    ...
]

Step 5: Run Migrations

Run the following commands to apply migrations:

python manage.py makemigrations
python manage.py migrate

Step 6: Test the Endpoints

Now you can test the authentication endpoints provided by dj-rest-auth such as:

/api/auth/login/
/api/auth/logout/
/api/auth/password/reset/
/api/auth/password/change/

Optional: Using JWT

If you want to use JWT for authentication, you need to install djangorestframework-simplejwt and configure it:

pip install djangorestframework-simplejwt

Update settings.py:

INSTALLED_APPS = [
    ...
    'rest_framework_simplejwt.token_blacklist',
    ...
]

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

# Add the following settings if you want to configure JWT behavior
from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': True,
    'BLACKLIST_AFTER_ROTATION': True,
    'ALGORITHM': 'HS256',
    'SIGNING_KEY': SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUTH_HEADER_TYPES': ('Bearer',),
    'USER_ID_FIELD': 'id',
    'USER_ID_CLAIM': 'user_id',
    'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
    'TOKEN_TYPE_CLAIM': 'token_type',
    'JTI_CLAIM': 'jti',
}

Add JWT URLs to urls.py:

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
    TokenVerifyView,
)

urlpatterns = [
    ...
    path('api/auth/jwt/create/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/auth/jwt/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    path('api/auth/jwt/verify/', TokenVerifyView.as_view(), name='token_verify'),
    ...
]

With these steps, you can use dj-rest-auth for basic authentication features without needing django-allauth. If you require advanced user registration, social login, and other features, consider integrating django-allauth into your project.


Customize LoginView in dj-rest-auth

Customize LoginView in dj-rest-auth

Create a new file views.py in your app and add the following:

from dj_rest_auth.views import LoginView

class CustomLoginView(LoginView):
    # Customize the login view
    def get_response(self):
        # Custom response logic
        pass
from dj_rest_auth.views import LoginView
from rest_framework.response import Response
from rest_framework import status
from rest_framework_simplejwt.tokens import RefreshToken

class CustomLoginView(LoginView):
    def get_response(self):
        # Get the serializer class for the response
        serializer_class = self.get_response_serializer()

        # Serialize the token
        serializer = serializer_class(instance=self.token, context=self.get_serializer_context())

        # Create tokens manually
        user = self.user
        refresh = RefreshToken.for_user(user)
        access_token = str(refresh.access_token)
        refresh_token = str(refresh)

        # Prepare response data
        response_data = {
            'access': access_token,
            'refresh': refresh_token,
        }

        # Return the custom response
        response = Response(response_data, status=status.HTTP_200_OK)
        return response

Update your urls.py to use the custom login view:

from django.urls import path, include
from .views import CustomLoginView

urlpatterns = [
    path('api/auth/login/', CustomLoginView.as_view(), name='custom_login'),
    path('api/auth/', include('dj_rest_auth.urls')),
    path('api/auth/signup/', include('dj_rest_auth.registration.urls')),
    # Other app URLs
]

Customizing the Serializer (Optional)

If you need to customize the serializer used in LoginView, you can subclass the default serializer and override its methods. Here’s an example:

Custom Serializer

# serializers.py

from dj_rest_auth.serializers import LoginSerializer

class CustomLoginSerializer(LoginSerializer):
    def validate(self, attrs):
        # Custom validation logic
        data = super().validate(attrs)
        # Add any custom response data here
        return data

Use Custom Serializer in Custom View

# views.py

from .serializers import CustomLoginSerializer

class CustomLoginView(LoginView):
    serializer_class = CustomLoginSerializer

    def get_response(self):
        # Custom response logic
        ...

Conclusion

The serializer in dj-rest-auth's LoginView is used to convert the authentication token into a response format. In your CustomLoginView, you override this behavior to manually create JWT tokens and format the response data. If needed, you can also customize the serializer to add additional validation or response data.


Manually Token Creation & Custom Serializer

If you still want to customize or add additional data using a serializer, you can do so by defining a custom serializer and using it to serialize additional user data. Here’s how you can achieve that:

# serializers.py

from rest_framework import serializers
from dj_rest_auth.serializers import LoginSerializer

class CustomLoginSerializer(LoginSerializer):
    access = serializers.CharField(read_only=True)
    refresh = serializers.CharField(read_only=True)

    def validate(self, attrs):
        data = super().validate(attrs)
        user = self.user

        # Manually create JWT tokens
        refresh = RefreshToken.for_user(user)
        data['access'] = str(refresh.access_token)
        data['refresh'] = str(refresh)

        # Add any custom response data here
        return data
# views.py

from .serializers import CustomLoginSerializer

class CustomLoginView(LoginView):
    serializer_class = CustomLoginSerializer

    def get_response(self):
        serializer_class = self.get_response_serializer()
        serializer = serializer_class(instance=self.token, context=self.get_serializer_context())

        response_data = serializer.data
        response = Response(response_data, status=status.HTTP_200_OK)
        return response

Explanation

  1. Custom Serializer:

    • The CustomLoginSerializer subclass extends LoginSerializer and manually adds the access and refresh fields to the response data in the validate method.
  2. Use Custom Serializer in Custom View:

    • In CustomLoginView, the custom serializer is specified by setting serializer_class = CustomLoginSerializer.
    • The get_response method uses the custom serializer to serialize the response data.

By following this approach, you can customize the login response to include JWT tokens and any additional data you need. This method ensures that the response is serialized properly, adhering to the structure and validation rules defined in the custom serializer.


Reference