1
votes

I can get a correct token when calling the URL /token/ but I wish to create a token manually for the user when /login/ is called.

urls.py:

    from django.urls import path
    from . import views
    from .views import MyTokenObtainPairView

    from rest_framework_simplejwt.views import (
        TokenRefreshView,
        TokenVerifyView
    )

    urlpatterns = [
        path('', views.api_root),
        path('register/', views.register),
        path('login/', views.login),
        path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
        path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
        path('token/verify/', TokenVerifyView.as_view(), name='token_verify'),
    ]

views.py:

@api_view(['POST'])
def login(request):
    email = request.data.get('email')
    password = request.data.get('password')
    user = get_object_or_404(User, email=email)

    if make_password(password) == user.password:
        if not user.is_active:
            return Response({"error": "User is not active"}, status=400)
        tokens = MyTokenObtainPairView.get_token(user)
        parse_token = {
            'refresh': str(tokens),
            'access': str(tokens.access_token),
        }
        return Response(status=200, data=parse_token)
    else:
        return Response(status=401)

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        refresh = self.get_token(self.user)
        data['refresh'] = str(refresh)
        data['access'] = str(refresh.access_token)

        # Add extra responses here
        data['username'] = self.user.username
        data['groups'] = self.user.groups.values_list('name', flat=True)
        data['test'] = '1234'
        return data

class MyTokenObtainPairView(TokenObtainPairView):
    serializer_class = MyTokenObtainPairSerializer

How do I modify this line to get my token for a specific user? tokens = MyTokenObtainPairView.get_token(user)

I have read the doc about manually create token by importing this: from rest_framework_simplejwt.tokens import RefreshToken but it is not adding the payload into the token...

if make_password(password) == user.password: will never succeed, since it will use a different salt.Willem Van Onsem
Ohhhh actually I modified my code a little bit before posting here due to a bit security concerns... I was doing make_password(password, salt=salt, hasher='default') == user.password to verify the passwordKaren Azuma
please use authenticate instead of checking credentials yourself docs.djangoproject.com/en/4.0/topics/auth/default/… This will for example also generate a password in case no user can be found to avoid hacking the system through time analysis.Willem Van Onsem
Thanks! That's a better way of checking passwordKaren Azuma