Расширение django-graphql-auth для ограничения имени пользователя, паролей и электронной почты
Я использую Django v 3.2 и django-graphql-auth v 0.3.16
У меня есть пользовательский пользователь (и менеджер пользователей), определенный следующим образом:
models.py
class CustomUser(AbstractUser):
USERNAME_FIELD='username'
EMAIL_FIELD='email'
# ...
objects = CustomUserManager()
managers.py
class CustomUserManager(BaseUserManager):
# ...
def create_user(self, email, password, **extra_fields):
if not is_valid_email(email):
raise ValueError(_('Bad email'))
username = extra_fields.get('username')
if not is_acceptable_username(username)):
raise ValueError(_('You cannot use this username'))
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
"""
Create and save a SuperUser with the given email and password.
"""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(email, password, **extra_fields)
settings.py
# ....
AUTH_USER_MODEL='myapp.CustomUser'
schema.py
import graphene
from graphql_auth import mutations
from graphql_auth.schema import MeQuery, UserQuery
class AuthMutation(graphene.ObjectType):
register = mutations.Register.Field()
verify_account = mutations.VerifyAccount.Field()
class Query(UserQuery, MeQuery, graphene.ObjectType):
pass
class Mutation(AuthMutation, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query, mutation=Mutation)
Я пытаюсь зарегистрировать нового пользователя через следующую мутацию:
mutation {
register(
email: "memyself@somebad-domain.com",
username: "badword1",
password1: "1234",
password2: "1234"
) {
success
errors
token
}
}
И я получаю следующий ответ:
{
"data": {
"register": {
"success": true,
"errors": null,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImJhZHdvcmQxIiwiZXhwIjoxNjY5OTEzNDIzLCJvcmlnSWF0IjoxNjY5OTEzMTIzfQ.TZ-copVrhUUsuLpozi18THjprGMnAGsBwpnyWORc16M"
}
}
}
Ожидаемым результатом будет то, что мутация GraphQL вернет код отказа, основанный на электронной почте, имени пользователя и пароле - все они были указаны специально, чтобы быть отвергнутыми.
Почему django-graphql-auth не использует мой пользовательский менеджер для создания объектов - и как мне исправить это, чтобы я мог реализовать свои собственные валидации (например, для правильной проверки/валидации имени пользователя и email)?
Похоже, что вы определили свою собственную модель CustomUser и CustomUserManager, но не используете их в файле schema.py. Чтобы использовать пользовательскую модель пользователя и менеджер, вам нужно указать их при создании класса AuthMutation в файле schema.py.
Вот пример того, как можно указать пользовательскую модель и менеджера при создании класса AuthMutation:
import graphene
from graphql_auth import mutations
from graphql_auth.schema import MeQuery, UserQuery
from myapp.models import CustomUser
from myapp.managers import CustomUserManager
class AuthMutation(graphene.ObjectType):
register = mutations.Register.Field(
user_model=CustomUser,
user_manager=CustomUserManager
)
verify_account = mutations.VerifyAccount.Field()
class Query(UserQuery, MeQuery, graphene.ObjectType):
pass
class Mutation(AuthMutation, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query, mutation=Mutation)
Указав вашу пользовательскую модель пользователя и менеджера при создании класса AuthMutation, django-graphql-auth будет использовать вашу пользовательскую реализацию методов create_user и create_superuser при обработке мутации регистра. Это позволит применять вашу пользовательскую проверку при создании новых пользователей.
Надеюсь, это поможет! Дайте мне знать, если у вас возникнут другие вопросы.
Django
и django-graphql-auth
использует ваш CustomUserManager
наверняка. Но, django-graphql-auth
использует метод модели save(...)
для создания объекта.
Вот как происходит выполнение -
- Инициирует
Register
и таким образомRegisterMixin
- Вызывает
Register.resolve_mutation(...)
и инициализируетRegisterForm
- Вызывает метод
save()
формы и вызывает методsave()
модели и таким образом был создан новыйUser
объект.
Как я могу проверить данные?
Я бы рассмотрел возможность создания подкласса Register
и переопределения метода resolve_mutation(...)
.
import graphene
from graphql_auth import mutations
class CustomRegister(mutations.Register):
@classmethod
def resolve_mutation(cls, root, info, **kwargs):
# do some validations here
# Example -
username = kwargs.get("username")
if username == "admin":
return cls(success=False, errors="Nice error message")
return super().resolve_mutation(root, info, **kwargs)
и затем, я бы определил это CustomRegister
в AuthMutation
class AuthMutation(graphene.ObjectType):
register = CustomRegister.Field()