API регистра аутентификации Django - PullRequest
1 голос
/ 12 апреля 2019

Я пытаюсь зарегистрировать пользователей в модуле аутентификации django через вызов API, но пользователи регистрируются без хеширования пароля, что, как я подозреваю, приводит к сбою аутентификации.Регистрация пользователей через форму администратора является хэшированием пароля и, следовательно, работает.

Я разработал свою собственную модель User, расширив AbstractBaseUser, а также создал UserManager, расширяющий BaseUserManager и определив методы create_user и create_superuser.Я разработал простой сериализатор для него.Я где-то читал, что пароль может быть хэширован только в том случае, если я разработал форму Admin, и поэтому я сделал это.В этой форме я следовал документации django и разработал clean_password и функции сохранения.Я также зарегистрировал эти формы в приложении admin.py.Наконец, я создал APIView для запросов POST, куда я отправляю регистрацию json и использую сериализатор для проверки и сохранения.

модель

class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError('The given email must be set')

        user = self.model(
            email=self.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password, **extra_fields):
        user = self.create_user(email,
                                password=password,
                                **extra_fields)
        user.is_admin = True
        user.save(using=self._db)
        return user

class User(AbstractBaseUser):
    email = models.EmailField(max_length=40, unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    photo_path = models.CharField(max_length=30, blank=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def save(self, *args, **kwargs):
        super(User, self).save(*args, **kwargs)
        return self

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin

сериализатор

class UserSerializer(serializers.ModelSerializer):
    class Meta(object):
        model = User
        fields = ('id', 'email', 'first_name', 'last_name', 'password')
        extra_kwargs = {'password': {'write_only': True}}

формы

class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email', 'photo_path')

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

class UserChangeForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ('email', 'photo_path', 'password')

    def clean_password(self):
        return self.initial["password"]

admin.py

class UserAdmin(BaseUserAdmin):
    form = UserChangeForm
    add_form = UserCreationForm

    list_display = ('email', 'first_name', 'is_staff')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password')}),
        ('Personal info', {'fields': ('first_name',)}),
        ('Permissions', {'fields': ('is_admin',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2')}
         ),
    )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

admin.site.register(User, UserAdmin)

посмотреть сообщение

class CreateUserAPIView(APIView):
    permission_classes = (AllowAny,)

    def post(self, request):
        user = request.data
        serializer = UserSerializer(data=user)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

Я ожидал получить пользователя в БД с хешированным паролем, как при создании пользователя в админ-панели.но я получаю пользователя, созданного с помощью простого текстового пароля.

Ответы [ 3 ]

1 голос
/ 12 апреля 2019

Что бы я сделал, это следующее в вашем сериализаторе.Обратите внимание на set_password.Таким образом, вы убедитесь, что он хешируется

0 голосов
/ 12 апреля 2019

Извините за быстрый автоответ, но я обнаружил, что почтовый индекс просмотра фактически не выполнял код моей модели create_user.Я не знаю, что связывало метод .save () сериализатора с системой аутентификации, но он все еще создавал пользователей.Я оставлю этот вопрос открытым, чтобы кто-то мог объяснить, что происходит.Чтобы это работало, я сделал следующие изменения:

class CreateUserAPIView(APIView):
   permission_classes = (AllowAny,)

   def post(self, request):
       user = User.objects.create_user(request.data['email'], request.data['password']);
       return Response(user, status=status.HTTP_201_CREATED)
0 голосов
/ 12 апреля 2019

Если вы используете md5 для хэширования, вы можете использовать модуль hashlib и хэшировать пароль перед сохранением в create_superuser

form hashlib import md5

def create_superuser(self, email, password, **extra_fields):
    user = self.create_user(email,password=md5(password),**extra_fields)
    user.is_admin = True
    user.save(using=self._db)
    return user
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...