Reputation: 2645
I have an issue posting/getting any requests after JWT login. (I am using the djangorestframework-jwt library) The user succesfully logs in, the app returns the json token but when I use this token for the next requests I get
{
"detail": "Authentication credentials were not provided."
}
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
JWT_AUTH = {
'JWT_ALLOW_REFRESH': True,
'JWT_EXPIRATION_DELTA': datetime.timedelta(hours=1),
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
}
Login View
def post(self, request, format=None):
if not request.data:
return Response({'Error': "Please provide username/password"}, status=status.HTTP_400_BAD_REQUEST)
username = request.data['username']
password = request.data['password']
try:
user = User.objects.get(email=username, password=password)
except User.DoesNotExist:
return Response({'Error': "Invalid username/password"}, status=status.HTTP_400_BAD_REQUEST)
if user:
payload = {
'id': user.id,
'email': user.email,
'first_name': user.first_name
}
jwt_token = jwt.encode(payload, "SECRET_KEY") # to be changed
return Response({'token': jwt_token}, status=status.HTTP_200_OK)
and then every other view contains
authentication_class = (JSONWebTokenAuthentication,)
permission_classes = (IsAuthenticated,)
I have tested both with postman and curl but I get the same error. Not sure if there is an error with the header format or if there is smth else I'm missing. Any help would be greatly appreciated!
EDIT: I have changed my settings to
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
but now I get that
{
"detail": "Error decoding signature."
}
EDIT: I think the issue is that jwt_token = jwt.encode(payload, 'SECRET_KEY')
might return a token that is not recognised...if i use the token generated by obtain_jwt_token
then i can query any endpoint. Could anyone explain this?
EDIT: so I changed to jwt_token = jwt_encode_handler(payload)
and the settings file contains the JWT_SECRET_KEY
(when i verify the token i receive after login on jwt, it is indeed the right token with the right payload and secret) but it's still not recognised "detail": "Invalid signature."
Upvotes: 1
Views: 2569
Reputation: 2645
I managed to solve my problem. When authenticating a user I was checking against a custom user
table that I had created earlier, which was different from the django's auth_user
table. I changed django's settings to use my custom users table and then using the token from the authentication worked for the other requests as well.
AUTH_USER_MODEL = 'main.User'
Upvotes: 1
Reputation: 1608
The problem is you encode the JWT by using "SECRET KEY" and decode using another key. The default secret key used by jwt is settings.SECRET_KEY. But when you create a custom jwt token you uses a string as secret "SECRET_KEY". But you use default jwt verification which automatically uses settings.SECRET_KEY.
So add 'JWT_SECRET_KEY': settings.SECRET_KEY,
in to your JWT settings and use this key for encode and decode.
Ex:
jwt_token = jwt.encode(payload, settings.SECRET_KEY)
or you can override the jwt verification and create your own.
Upvotes: -1