Как предоставить типы пользователей при регистрации в качестве пользователя с помощью google в Django rest framework
У меня есть модель customeuser, которая наследуется от AbstractUser. Я также использовал регистрацию с помощью функции google. Но теперь, позже в моем проекте, мне нужно добавить типы пользователей. Например, пользователь может быть владельцем, менеджером и сотрудником, и у них есть свои привилегии.
Моя модель:
ROLE = (('owner','OWNER'),('manager','MANAGER'),('staff','STAFF'))
class User(AbstractUser):
SOCIAL_AUTH_PROVIDERS = (
("GOOGLE", ("GOOGLE")),
("FACEBOOK", ("FACEBOOK")),
("TWITTER", ("TWITTER")),
)
name = CharField(_("Name of User"), blank=True, max_length=255)
email = EmailField(_("Email Address"), unique=True)
mobile = CharField(
_("Mobile Number"), max_length=16, unique=True, blank=True, null=True
)
email_verified = BooleanField(default=False)
social_auth = CharField(
choices=SOCIAL_AUTH_PROVIDERS,
max_length=100,
blank=True,
null=True,
)
role = models.CharField(max_length=15, choices=ROLE, default='staff') #added this field later
first_name = None
last_name = None
username = None
USERNAME_FIELD = "email"
REQUIRED_FIELDS = []
objects = CustomUserManager()
Здесь я перенес новую роль поля в модель пользователя, потому что мне это было необходимо из-за бизнес-требований.
Изменение в моем сериализаторе будет выглядеть следующим образом.
class UserRegisterationSerializer(serializers.ModelSerializer):
def validate(self, data):
email = data["email"]
password = data.get("password")
role = data["role"] #added this part
mesg = "This email has been already registered."
if User.objects.filter(email=email).exists():
raise serializers.ValidationError({"email": mesg})
if password:
user = User(email=email,role=role) #added role here too
try:
validate_password(password=password, user=user)
except Exception as e:
raise serializers.ValidationError({"password": e.messages})
return data
Здесь при регистрации на основе обычного email и пароля мы можем сделать это легко, как показано выше. Я просто получаю роль из данных и использую ее для создания пользователя с email и ролью. Проблема возникает, когда мы пытаемся зарегистрироваться с помощью google sign up.
Мой взгляд из Google:
class GoogleSocialAuthView(GenericAPIView):
serializer_class = GoogleSocialAuthSerializer
permission_classes = ()
def post(self, request):
serializer = self.serializer_class(
data=request.data, context={"request": request}
)
serializer.is_valid(raise_exception=True)
return Response(serializer.validated_data, status=status.HTTP_200_OK)
Мой сериализатор Google:
class GoogleSocialAuthSerializer(serializers.Serializer):
id_token = serializers.CharField()
@classmethod
def get_token(cls, user):
return RefreshToken.for_user(user)
def get_user_details(self, user):
refresh = self.get_token(user)
personal_info_added = bool(user.mobile)
course_info_added = (
StudentLevel.objects.exclude(subjects__isnull=True)
.filter(student__user_id=user.pk)
.exists()
)
response = {
"personal_info_added": personal_info_added,
"course_info_added": course_info_added,
"refresh": str(refresh),
"access": str(refresh.access_token),
}
return response
def validate(self, data):
id_token = data.pop("id_token")
user_data = Google.validate(id_token)
try:
user_data["sub"]
except Exception:
raise serializers.ValidationError(
{"id_token": ["The token is invalid or expired. Please login again."]}
)
if user_data["aud"] != SOCIAL_AUTH_GOOGLE_OAUTH2_KEY:
raise AuthenticationFailed("Invalid Google oauth key")
email = user_data["email"]
name = user_data["name"]
social_auth_provider = "GOOGLE"
user_data = User.objects.filter(email=email)
if user_data.exists():
user_details = self.get_user_details(user_data.first())
return user_details
else:
user = User.objects.create(
email=email, name=name, social_auth=social_auth_provider
)
user.email_verified = True
user.save()
user_details = self.get_user_details(user)
return user_details
Итак, есть ли способ создать пользователя, предварительно назначив ему роль? Например, зарегистрироваться как менеджер или как владелец, используя google signup. Если да, то какие изменения нужно сделать в сериализаторе google?