Как создать несколько типов пользователей с помощью google OAuth в Django
Я работаю на Django и делаю систему управления школой, где я даю возможность ученикам и учителям входить и регистрироваться через Google OAuth .
Вот мои модели
from django.db import models
class Student(models.Model):
first= models.CharField(max_length = 100 , blank = False , null = False)
last = models.CharField(max_length = 100 , blank = False , null = False)
user = models.OneToOneField(User , on_delete = models.CASCADE)
class_studying = models.ForeignKey("SchoolClass")
...
class Teacher(models.Model):
first= models.CharField(max_length = 100 , blank = False , null = False)
last = models.CharField(max_length = 100 , blank = False , null = False)
user = models.OneToOneField(User , on_delete = models.CASCADE)
classes_teaching = models.ManyToManyField("SchoolClass")
salary = models.DecimalField(max_digits =6 , decimal_places = 2)
...
Я использую google Oauth с пакетом django-allauth для регистрации, входа пользователей через google OAuth .
Здесь у меня есть возможность создать только один тип пользователя через Google OAuth с помощью сигналов. Либо я могу создать ученика, либо учителя. Но я хочу создать способ, чтобы я мог зарегистрировать как учителя, так и ученика через тот же OAuth. Я пробовал различные способы и применял несколько логических схем, чтобы понять это, но я не могу получить полноценное решение .
Signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save , sender = User )
def save_student(sender , instance , created , *args , **kwargs):
if created :
student = Student(user = instance)
student.save()
...
Я пытаюсь найти различные решения для решения этой проблемы, но не могу создать полноценное решение .
После создания пользователя. Он сохраняется в базе данных в модели пользователя. Я хочу создать связанное лицо в соответствии с потребностью.
Если учитель хочет создать учетную запись, ему должна быть предоставлена какая-то другая ссылка или форма регистрации через Google OAuth, а для ученика - другая. Мне это тоже не помогает.
Любая помощь была бы очень кстати. Спасибо.
Вам необходимо удалить сигнал и создать собственный поток аутентификации.
Идеальный способ - переопределить метод auth и создать свою собственную функцию. В функции auth мы получим тип пользователя (студент, преподаватель) и создадим студента или преподавателя на основе типа пользователя.
class GoogleSocialAuthView(GenericAPIView):
serializer_class = GoogleSocialAuthSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
data = (serializer.validated_data['auth_token'])
return Response(data, status=status.HTTP_200_OK)
Класс Серилаизер:
class GoogleSocialAuthSerializer(serializers.Serializer):
auth_token = serializers.CharField()
def validate_auth_token(self, auth_token):
user_data = google.Google.validate(auth_token)
try:
user_data['sub']
except:
raise serializers.ValidationError(
'The token is invalid or expired. Please login again.'
)
if user_data['aud'] != os.environ.get('GOOGLE_CLIENT_ID'):
raise AuthenticationFailed('oops, who are you?')
user_id = user_data['sub']
email = user_data['email']
provider = 'google'
name = email.split("@")[0]
return register_social_user(
provider=provider, user_id=user_id, email=email, name=name
)
Функция регистрации:
def register_social_user(provider, user_id, email, name):
filtered_user_by_email = BenjiUser.objects.filter(email=email)
data = {}
if filtered_user_by_email.exists():
if provider == filtered_user_by_email[0].auth_provider:
registered_user = authenticate(
username=name, password=os.environ.get('SOCIAL_SECRET')
)
refresh = RefreshToken.for_user(registered_user)
data['token'] = str(refresh.access_token)
user = CustomUser.objects.get(username=registered_user.username)
data['user'] = BenjiUserSerializer(instance=user).data
return data
else:
raise AuthenticationFailed(
detail='Please continue your login using ' + filtered_user_by_email[0].auth_provider)
else:
user = {
'username': generate_username(name), 'email': email,
'password': os.environ.get('SOCIAL_SECRET')
}
# TODO: Check user type and based on it create object.
user = CustomUser.objects.create_user(**user)
user.is_verified = True
user.save()
new_user = authenticate(
username=name, password=os.environ.get('SOCIAL_SECRET')
)
refresh = RefreshToken.for_user(new_user)
data['token'] = str(refresh.access_token)
from tenants.serializers import BenjiUserSerializer
data['user'] = CustomUserSerializer(instance=user).data
return data