Deepanshu Mehta
Deepanshu Mehta

Reputation: 121

How can i use Simple JWT for custom User Model

I am managing my User Model (for customers), but i don't know how can i use simple-jwt for my Customer Model with it's custom Login View.

models.py

from django.db import models

class Customer(models.Model):
   name = models.CharField(max_length=100)
   email = models.EmailField(max_length=100)
   password = models.CharField(max_length=100)

and also, i want to manage my customer session by saving the Refresh Token, can anyone please tell me how can i achieve that.

Upvotes: 7

Views: 16866

Answers (5)

Muteshi
Muteshi

Reputation: 1318

First install simple jwt with the command pip install djangorestframework-simplejwt You must then configure your django project to use the libary with following option in settings.py

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

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
    'ROTATE_REFRESH_TOKENS': False,
    'BLACKLIST_AFTER_ROTATION': True,
    'UPDATE_LAST_LOGIN': False,

    'ALGORITHM': 'HS256',
    'SIGNING_KEY': settings.SECRET_KEY,
    'VERIFYING_KEY': None,
    'AUDIENCE': None,
    'ISSUER': None,

    'AUTH_HEADER_TYPES': ('Bearer',),
    'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
    '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',

    'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
    'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
    'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}

In your root urls.py add the following

from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    ...
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ...
]

Simple JWT by default only sends user id in the token. You can customize it further to send more information in your serializers.py by doing the following

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    """Customizes JWT default Serializer to add more information about user"""
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['name'] = user.name
        token['email'] = user.email
        token['is_superuser'] = user.is_superuser
        token['is_staff'] = user.is_staff

        return token

Then in your views.py add the following

from users import serializers
class CustomTokenObtainPairView(TokenObtainPairView):
    # Replace the serializer with your custom
    serializer_class = serializers.CustomTokenObtainPairSerializer

You can read more here

To check out the JWT content, we can use JWT.io: here

In case you are using Javascript frameworks or vanilla JS, you can use a function like this here

Upvotes: 5

Jerry
Jerry

Reputation: 1

the easiest way is to create the token manually using simple jwt

from rest_framework_simplejwt.tokens import RefreshToken

def get_tokens_for_user(user): refresh = RefreshToken.for_user(user)

return {
    'refresh': str(refresh),
    'access': str(refresh.access_token),
}

you have the documentations here https://django-rest-framework-simplejwt.readthedocs.io/en/latest/creating_tokens_manually.html

Upvotes: 0

Deepanshu Mehta
Deepanshu Mehta

Reputation: 121

After some research, I came to the conclusion that Simple JWT doesn't have any special support for user models that are not derived from AbstactUserModel.

It means if you are managing the Customer model, either you need to extend it from AbstactUserModel or you should use jwt instead of Simple jwt.

Upvotes: 5

pyNoob
pyNoob

Reputation: 37

in your views.py file, import this

from rest_framework_simplejwt.tokens import RefreshToken

next, create a refresh token in def post - the one you use for logging in

def post(self, request):
    ...
    refresh = RefreshToken.for_user(user)
    ...

return the generated refresh token and access token in the response body

return Response(
    {
        'refresh': str(refresh),
        'access': str(refresh.access_token),
    },
    status = status.HTTP_200_OK
)

What I have suggested is a simple and super basic implementation of what I believe you are looking for. I got it from here. But if you want a better and more customized, neater implementation, refer this article.

Upvotes: 1

Duilio
Duilio

Reputation: 1036

I could fix this problem adding 'rest_framework_simplejwt' to INSTALLED_APPS after the app that has the custom user model.

Upvotes: 0

Related Questions