jpadilla / django-rest-framework-jwt

JSON Web Token Authentication support for Django REST Framework
http://jpadilla.github.io/django-rest-framework-jwt/
MIT License
3.19k stars 649 forks source link

Is there someone tried to ReWite the obtain_token and verify_token ? #456

Open ghost opened 6 years ago

ghost commented 6 years ago

I have try it that i want to solve thsi two problems,

then i tred it in this view, but the msg in last line msg can not be use .

# coding:utf-8

from rest_framework import serializers
from rest_framework_jwt.compat import get_username_field, PasswordField, Serializer
from django.contrib.auth import authenticate, get_user_model
from rest_framework_jwt.serializers import _, jwt_payload_handler, jwt_encode_handler

from rest_framework_jwt.utils import jwt_response_payload_handler
class CustomizeJSONWebTokenSerializer(Serializer):
    def __init__(self, *args, **kwargs):
        super(CustomizeJSONWebTokenSerializer, self).__init__(*args, **kwargs)

        self.fields[self.username_field] = serializers.CharField()
        self.fields['password'] = PasswordField(write_only=True)

    @property
    def username_field(self):
        return get_username_field()

    def validate(self, attrs):
        credentials = {
            self.username_field: attrs.get(self.username_field),
            'password': attrs.get('password')
        }

        if all(credentials.values()):
            user = authenticate(**credentials)

            if user:
                if not user.is_active:
                    msg = _('User account is disabled.')
                    raise serializers.ValidationError(msg)

                payload = jwt_payload_handler(user)

                 ## The func that will write here while login seccuss
                return {
                    'token': jwt_encode_handler(payload),
                    'user': user
                }
            else:

                ## The func that will write here while login failed
                msg = _('Unable to login with provided credentials.')
                raise serializers.ValidationError(msg)
        else:
            ## there
            # YOU can rewrite this msg, but no active 
            msg = _('Must include "{username_field}" and "password".')
            msg = msg.format(username_field=self.username_field)
            raise serializers.ValidationError(msg)

from rest_framework_jwt.views import JSONWebTokenAPIView

class CustomizeObtainJSONWebToken(JSONWebTokenAPIView):
    serializer_class = CustomizeJSONWebTokenSerializer

customize_obtain_jwt_token = CustomizeObtainJSONWebToken.as_view()
pkariz commented 6 years ago

1) you can use JWT_GET_USER_SECRET_KEY, so you basically generate a secret key from the last_login. Mix it with user's password (hash) or something similar. This will invalidate the previous tokens on new login or on password change. 2) store user's unsuccessful attempts somewhere and just check them in the authenticate method

ghost commented 5 years ago

@pkariz thank you for your anwser, the first i have run well with your advice, but by the second question how could i do , the request.Meta["remote_addr"] can not be got from the Serilizer-obj because the request not in kwargs keys , i have replaced it by making a login middleware after the view return . but i think it's not a very good idea