DjangoRestFramework_JWT игнорирует полезную нагрузку в пользовательском обработчике - PullRequest
0 голосов
/ 29 января 2020

Я создал этот пользовательский jwt_payload_handler для jwt, чтобы он мог знать пароль. Если пользователь меняет свой пароль, я хочу, чтобы срок действия предыдущих токенов истек. Но даже при том, что у меня есть собственный обработчик, по какой-то причине drf jwt игнорирует изменения и все еще принимает прошлые токены после того, как я изменю пароль пользователя или изменю строковое значение password_last_change.

Мне не хватает другой конфигурации?

jwt_payload_handler:

def jwt_payload_handler(user):
    username_field = get_username_field()
    username = get_username(user)
    password_last_change = user.password_last_change  # getting json not serializable error. constant string for now

    warnings.warn(
        'The following fields will be removed in the future: '
        '`email` and `user_id`. ',
        DeprecationWarning
    )

    payload = {
        'user_id': user.pk,
        'username': username,
        'password': user.password,
        'exp': (datetime.utcnow() +  api_settings.JWT_EXPIRATION_DELTA)  ,
        'password_last_change': 'test1',
    }
    if hasattr(user, 'email'):
        payload['email'] = user.email
    if isinstance(user.pk, uuid.UUID):
        payload['user_id'] = str(user.pk)

    payload[username_field] = username

    # Include original issued at time for a brand new token,
    # to allow token refresh
    if api_settings.JWT_ALLOW_REFRESH:
        payload['orig_iat'] = timegm(
            datetime.utcnow().utctimetuple()
        )

    if api_settings.JWT_AUDIENCE is not None:
        payload['aud'] = api_settings.JWT_AUDIENCE

    if api_settings.JWT_ISSUER is not None:
        payload['iss'] = api_settings.JWT_ISSUER

    return payload

1 Ответ

0 голосов
/ 29 января 2020

Я понял это. Вместо пользовательской функции jwt_payload_handler нам нужно установить значение JWT_GET_USER_SECRET_KEY в файле settings.py. По умолчанию это None, но он принимает функцию, которая принимает пользователя в качестве параметра и возвращает строку uuid. Если не настроено, секретный ключ conf django используется для всех пользователей. Но если установлено, у каждого пользователя будет свой секретный ключ.

При смене пароля также обновите uuid.

в пользовательской модели мы можем установить в какое-то поле:

class TestUser(AbstractBaseUser):
    jwt_secret = models.UUIDField(default=uuid.uuid4)

пример функции:

def jwt_get_secret_key(user_model):
    return user_model.jwt_secret 

в настройках:

JWT_AUTH = {
    ...
    'JWT_GET_USER_SECRET_KEY': 'path.to.jwt_get_secret_key'
    ...
}

Таким образом, в вашем представлении или сигнале после вызова метода set_password вы можете установить для user.secret_jwt новое значение:

user.secret_jwt = uuid.uuid4()
user.save()

, которое сделает предыдущий запрос недействительным.

...