I'm trying to implement django-rest-framework-jwt for authentication. I did all what jwt tutorials said (adding the setting, url and curl testing). and I did successfully obtain the token using 127.0.0.1:8000/api/auth/token/
in the browsable api.
but what I don't get is how to generate the token in the login process. My guess is to generate it in the LoginSerializer maybe? (or I misunderstood the concept!)
Here's what I have:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
# project/urls.py
url(r'^api/auth/token/', obtain_jwt_token),
login serializer and view:
class UserLoginSerializer(ModelSerializer):
token = CharField(allow_blank=True, read_only=True)
class Meta:
model = User
fields = ('username', 'password', 'token')
def validate(self, data):
username = data.get('username',None)
password = data['password']
user = authenticate(username=username, password=password)
if not user or not user.is_active:
raise ValidationError("Invalid username/password.")
# generate jwt token ??
# data['token'] = generated jwt token??
return data
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)
So what do I have to do?
Here is what i did.
from rest_framework_jwt.settings import api_settings
class LoginView(APIView):
'''
Post call for user login.
'''
def post(self, request, format=None):
serializer = LoginSerializer(data=request.data)
if serializer.is_valid():
# Check if user has valid credentials and return user instance else None
user = authenticate(username=serializer.validated_data['username'],
password=serializer.validated_data['password'])
if user is not None:
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return Response({'msg':'Login successful', 'token': token, 'is_login_success': True}, status=status.HTTP_200_OK)
else:
return Response({'msg': 'Credentials are not valid!'}, status=status.HTTP_400_BAD_REQUEST)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
But you dont have to do that since your 127.0.0.1:8000/api/auth/token/
is doing pretty exactly the same, unless you want to record something before logging in.
If you want more information how obtain_jwt_token
view works, its JSONWebTokenSerializer
will help you.