DRF использует немодельное поле для проверки учетных данных - PullRequest
0 голосов
/ 03 февраля 2019

Поэтому я пытался реализовать способ, позволяющий использовать функцию регистрации моего DRF REST API только в моих приложениях.Я знаю, что API может быть доступен любому, но я подумал о том, чтобы требовать поля client_id и client_secret, чтобы его могли использовать только приложения, зарегистрированные с моим протоколом Oauth2.

Я могу успешно войти в систему, используя Oauth2 для своих приложенийи доступ к ограниченной странице.Я могу зарегистрироваться в этой реализации, но выдает ошибку, что «У объекта пользователя нет атрибута client_id».

Это имеет смысл, потому что client_id от oauth2, но я только хочу, чтобы это поле было уверенным, что оноиспользуется только моими приложениями.

serializers.py

class UserSerializer(serializers.ModelSerializer):

    # Additional fields to verify if allowed to register with client info
    client_id = serializers.CharField(max_length=255)
    client_secret = serializers.CharField(max_length=255)

    class Meta:
        model = User # for the User model, use get_user_model for custom
        fields = ('id', 'username', 'password', 'email', 'first_name', 'last_name', 
            'client_id', 'client_secret',)
        extra_kwargs = {'password': {'write_only': True}}
        read_only_fields = ('id',)

    # override create method
    def create(self, validated_data):
        if validated_data['client_id'] != "OI430uPmYGKUJ6h2C7Ohjdn2C9i3WONVMi7WQvu0" and validated_data['client_secret'] != "X8KJNUjIeXf7I8jIbzjt4k92rs6OPxSUqKv9IeaP6YRpLsK8YZVDLK8RcFDqacH4hKSzkuuZET42VyMkIltQt8mUwi16DCGwFWX3fJf7ZxcDMKA6wOQKJnX1GKh9bQ7a":
            raise serializers.ValidationError("Not allowed to do this MATE!")

        user = User.objects.create(
            username=validated_data['username'],
            email=validated_data['email'],
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name']
            )

        user.set_password(validated_data['password'])
        user.save()

        return user

Я могу использовать его для регистрации пользователей, но выдает ошибку, сообщающую, что модель не содержит client_id.Я не уверен, как это исправить

Я использую oauth2_provider

1 Ответ

0 голосов
/ 03 февраля 2019

Ваше представление об идентификаторе и секрете клиента правильное, особенно при использовании протокола аутентификации / авторизации OAuth2, но вы реализуете его неправильно.

Во-первых, позвольте мне посоветовать вам передать их в заголовкипоскольку они являются учетными данными аутентификации, так же как заголовок авторизации.Это обычная практика.Вы можете создать собственные заголовки для них или добавить их в заголовок авторизации.В любом случае, его следует обрабатывать не на уровне представления, а на уровне аутентификации.

Во-вторых, если вы собираетесь добавить немодельное поле в сериализатор модели, то вам следует убедиться, чтоон недоступен для записи, так как сериализатор вызовет ошибки при построении его полей.

Глядя на документы Oauth2_provider , вы можете видеть, что аутентификация приложения с идентификатором клиента и секретом клиента уже реализована.

Сначала вы создаете приложение (например, ваше официальное клиентское приложение).Идентификатор клиента и секретные данные создаются для этого приложения.Затем при регистрации нового пользователя вы передаете этот токен, как в примере:

curl -X POST -d "grant_type=password&username=<user_name>&password=<password>" -u"<client_id>:<client_secret>" http://localhost:8000/o/token/

Это вернет учетные данные аутентификации для пользователя, который является уникальным для этого приложения (или клиента) и является тем, что необходимо длядальнейшие запросы.

Если вы хотите иметь возможность аутентифицировать приложение даже для незарегистрированных пользователей, просто используя учетные данные приложения, то вам следует реализовать собственный класс аутентификации, наследующий от oauth2_provider.contrib.rest_framework.OAuth2Authentication, и добавить туда логику проверки.Не забудьте использовать новый класс в качестве DEFAULT_AUTHENTICATION_CLASSES в настройках REST_FRAMEWORK

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...