djangodjango-rest-frameworkaccess-tokendjango-rest-framework-jwtdjango-rest-framework-simplejwt

How to extract payload from a jwt Expired Token


I have made a view where I send a Refresh Token to email for activation account purpose. If token is valid everything works fine. The problem is when jwt token expire, I want to be able in backend to extract payload (user_id) from token when jwt.decode throw ExpiredSignatureError and in this way be able to auto resend an Email based on user_id extracted from token.

Here is how I generate the token:

def activation_link(request, user, email):
    token = RefreshToken.for_user(user)
    
    curent_site = "localhost:3000"
    relative_link="/auth/confirm-email"
    
    link = 'http://' + curent_site + relative_link + "/" + str(token)
    html_message  = render_to_string('users/email_templates/activate_account.html',{
        'activation_link': link,
    })

    text_content = strip_tags(html_message) 
    email_subject = 'Activate your account'
    from_email = 'notsure@yahoo.com'
    to_email = email
@api_view(['POST'])
def ConfirmEmailView(request):
    try:
        activation_token = request.data['activation_token']
        payload = jwt.decode(activation_token,settings.SECRET_KEY,  algorithms=['HS256'])
        user = User.objects.get(id = payload['user_id'])
        if user.is_confirmed:
            return Response('Already verified!', status=status.HTTP_200_OK)  
        user.is_confirmed = True
        user.save()
        return Response(status=status.HTTP_202_ACCEPTED)

    except jwt.ExpiredSignatureError as identifier:

        // =>>> Here I want to decode activation_token  and extract user_id 

        return Response("Link- expired!", status=status.HTTP_403_FORBIDDEN)


    except Exception as e:
        print(e)
        return Response(status=status.HTTP_400_BAD_REQUEST)

Solution

  • Well, apparently the solution is easy:

    def ConfirmEmailView(request):
        try:
            activation_token = request.data['activation_token']
            payload = jwt.decode(activation_token,settings.SECRET_KEY,  algorithms=['HS256'])
            user = User.objects.get(id = payload['user_id'])
            if user.is_confirmed:
                return Response('Already verified!', status=status.HTTP_200_OK)  
            user.is_confirmed = True
            user.save()
            return Response(status=status.HTTP_202_ACCEPTED)
    
        except jwt.ExpiredSignatureError as identifier:
    
            # Here we are:
    
            payload = jwt.decode(request.data['activation_token'],settings.SECRET_KEY,  algorithms=['HS256'],options={"verify_signature": False}) 
            user_id = payload['user_id'];
    
            return Response({'user_id':user_id, status=status.HTTP_2OO_OK})
    

    By adding options={"verify_signature": False} is posible to decode the token just fine!