2

I want to integrate JWT to my User login API for Authentication. How can I integrate it with my existing code that I have added below. In the code I have added a dummy token that needs to be changed accordingly. Thank you.

Adding some relevant parts of code from my django project for reference:

Serializers

class UserLoginSerializer(ModelSerializer):
token = CharField(allow_blank=True, read_only=True)

class Meta:
    model = User
    fields = [
        'username',
        'password',
        'token',
    ]
    extra_kwargs = {"password":
                        {"write_only": True}
                    }

def validate(self, data):
    user_obj = None
    username = data.get("username", None)
    password = data["password"]
    if not username:
        raise ValidationError("Kullanıcı adı gerekli.")

    user = User.objects.filter(
        Q(username=username)
        ).distinct()
    user = user.exclude(email__isnull=True).exclude(email__iexact='')
    if user.exists() and user.count() == 1:
        user = user.first()
    else:
        raise ValidationError("Böyle bir Kullanıcı Adı yoktur.")

    if user_obj:
        if not user_obj.check_password(password):
            raise ValidationError("Tekrar deneyiniz.")
    data["token"] = "asdasdasdasd"
    return data

Views

class UserLoginAPIView(APIView):
permission_classes = [AllowAny]
serializer_class = UserLoginSerializer

def post(self, request, *args, **kwargs):
    data = request.data
    serializer = UserLoginSerializer(data=data)
    if serializer.is_valid(raise_exception=True):
        new_data = serializer.data
        return Response(new_data, status=HTTP_200_OK)
    return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

Settings

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
    ),
'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication',
    'rest_framework.authentication.BasicAuthentication',
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
}

urls

urlpatterns = [
    url(r'^login/$', UserLoginAPIView.as_view(), name='login'),
    url(r'^api-token-auth/', obtain_jwt_token),
    url(r'^api-token-refresh/', refresh_jwt_token),
    url(r'^api-token-verify/', verify_jwt_token),
    url(r'^register/$', UserCreateAPIView.as_view(), name='register'),
]
2
  • Have you looked into this package? github.com/GetBlimp/django-rest-framework-jwt Commented Jul 28, 2016 at 11:54
  • Yes I've already looked this package. But I dont understand exactly how can i change. If there is any example about it, please let me know. Thank you Commented Jul 28, 2016 at 13:43

5 Answers 5

3

You can use its in-built view rest_framework_jwt.views.obtain_jwt_token for User Login.

It creates a token.

And then you need to go to RestrictedView and use the token for authentication. That's all.

Sign up to request clarification or add additional context in comments.

Comments

2

More easiest way to use JWT in Python using the library called PyJWT

Steps:

  1. Install pip package of jwt ($ pip install PyJWT)
  2. At the views.py:

    import jwt
    
  3. Then goto the place, where you wanted to generate a token, then use it as follows:

    encoded = jwt.encode({'email': uemail, 'phone':phone}, 'MySecretKey', algorithm='HS256')
    
  4. Printing or adding encoded variable in the response, will give the response.

Comments

0

You can try doing something like this:

First, install pip install djangorestframework-jwt.

settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
}

def jwt_response_payload_handler(token, user, request, *args, **kwargs):
    data = {
        "token": token,
        "user": "{}".format(user.id),
        "userid": user.id,
        "active": user.is_active
    }
    return data

JWT_AUTH = {
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'jwt_response_payload_handler',
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=180),
    'JWT_ALLOW_REFRESH': False,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=30),
    'JWT_SECRET_KEY': 'generate_a_secret_key',
}

serializers.py:

from rest_framework import serializers
from rest_framework.authtoken.models import Token

class TokenSerializer(serializers.ModelSerializer):
    class Meta:
        model = Token
        fields = ('key',)

Anywhere authenication_classes apply in your views, you'll want to add:

from rest_framework_jwt.authentication import JSONWebTokenAuthentication

I hope that helps you!

Comments

0

I implemented a method for Sign In with JWT and what it does is:

  1. Fetches the email and password that is send with the request and converts it into a string variable
  2. I check if the email already exists in the custom user model i made.
  3. If the user already exists, i convert the object model to dictionary so that i can get its particular password.
  4. In that i match the password corresponding to user model and the password that is send with the post request.
  5. if the email exists in the user model and the password corresponding to that user model matches the password that is sent with the post request i use the pyJWT to make the JWT with my custom data and return the response.
  6. In all other cases the email and password don't match and i return "No Match"

Suppose the request is {"email":"[email protected]", "password":"12345" }

    @api_view(['POST'])
    def signin(request):

    email = list(request.data.values())[0] #gets email value from post request {"email":"[email protected]", "password":"123"} -> this [email protected]
    password = list(request.data.values())[1] #gets password value from post request {"email":"[email protected]", "password":"123"} -> this 123

    usr = User.objects.filter(email=email).exists() #checks if email exists
    if usr:
      dictionary = User.objects.filter(email=email).values()[0] #converts object to dictionary for accessing data like dictionary["password"] dictionary["first_name"] etc
      if usr and dictionary["password"] == password: #check if email and its corresponing password stored matches the password that is sent
        branch = dictionary["branch"]
        id = dictionary["id"]
        encoded_jwt = jwt.encode({'email': email,}, 'secret', algorithm='HS256')
        return Response({'token':encoded_jwt,'email':email,'branch':branch,'id':id})
      else: 
        return Response({'No Match'})
    return Response({'No Match'})

Comments

0

I implemented a method for Sign In with JWT and what it does is:

  1. Fetches the email and password that is send with the request and converts it into a string variable
  2. I check if the email already exists in the custom user model i made.
  3. If the user already exists, i convert the object model to dictionary so that i can get its particular password.
  4. In that i match the password corresponding to user model and the password that is send with the post request.
  5. if the email exists in the user model and the password corresponding to that user model matches the password that is sent with the post request i use the pyJWT to make the JWT with my custom data and return the response.
  6. In all other cases the email and password don't match and i return "No Match"

Suppose the request is {"email":"[email protected]", "password":"12345" }

views.py

    @api_view(['POST'])
    def signin(request):

    email = list(request.data.values())[0] #gets email value from post request {"email":"[email protected]", "password":"123"} -> this [email protected]
    password = list(request.data.values())[1] #gets password value from post request {"email":"[email protected]", "password":"123"} -> this 123

    usr = User.objects.filter(email=email).exists() #checks if email exists
    if usr:
      dictionary = User.objects.filter(email=email).values()[0] #converts object to dictionary for accessing data like dictionary["password"] dictionary["first_name"] etc
      if usr and dictionary["password"] == password: #check if email and its corresponing password stored matches the password that is sent
        branch = dictionary["branch"]
        id = dictionary["id"]
        encoded_jwt = jwt.encode({'email': email,}, 'secret', algorithm='HS256')
        return Response({'token':encoded_jwt,'email':email,'branch':branch,'id':id})
      else: 
        return Response({'No Match'})
    return Response({'No Match'})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.