0

Hello I would like help I have been trying to learn how to create token with django rest framework and pyjwt But whenever I do it when I am going to use login it gives me an error I would like to know if it is due to the code since I have seen several videos and I have the same code or it is due to something on my computer and if so, how could I solve it, the error is the next

Internal Server Error: /api/login Traceback (most recent call last): File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner response = get_response(request) File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\django\views\generic\base.py", line 70, in view return self.dispatch(request, *args, **kwargs) File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\rest_framework\views.py", line 509, in dispatch response = self.handle_exception(exc) File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\rest_framework\views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception raise exc File "D:\Users\ferna\Documents\Cursos\Youtube\auth.env\lib\site-packages\rest_framework\views.py", line 506, in dispatch response = handler(request, *args, **kwargs) File "D:\Users\ferna\Documents\Cursos\Youtube\auth\users\views.py", line 37, in post token = jwt.encode(payload, 'secret', algorithm='HS256').decode('utf-8') AttributeError: 'str' object has no attribute 'decode' [07/May/2021 21:18:23] ←[35;1m"POST /api/login HTTP/1.1" 500 96900←[0m

the code for view it's

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed
from .serializers import UserSerializer
from .models import User
import jwt, datetime


# Create your views here.
class RegisterView(APIView):
    def post(self, request):
        serializer = UserSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)


class LoginView(APIView):
    def post(self, request):
        email = request.data['email']
        password = request.data['password']

        user = User.objects.filter(email=email).first()

        if user is None:
            raise AuthenticationFailed('User not found!')

        if not user.check_password(password):
            raise AuthenticationFailed('Incorrect password!')

        payload = {
            'id': user.id,
            'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=60),
            'iat': datetime.datetime.utcnow()
        }

        token = jwt.encode(payload, 'secret', algorithm='HS256').decode('utf-8')

        response = Response()

        response.set_cookie(key='jwt', value=token, httponly=True)
        response.data = {
            'jwt': token
        }
        return response 
  • Looks like the package `PyJWT` v2.0.0 has a bug. Try to change it's version. Source: https://stackoverflow.com/a/65484529/7285863 – ishak O. May 08 '21 at 01:35

1 Answers1

0

I found actual problem.

The package PyJWT changed return type of jwt.encode(...) with version 2. From now it returns string instead of byte string. Link

After that use these codes:

encoded = jwt.encode({"some": "payload"}, key, algorithm="HS256")
result = jwt.decode(encoded, key, algorithms="HS256")

instead of that this:

result = jwt.encode(payload, 'secret', algorithm='HS256').decode('utf-8')
ishak O.
  • 168
  • 1
  • 2
  • 14