如何在Django中使用google OAuth创建多种类型的用户



我在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()
...

我正在试图找出不同的解决方案来解决这个问题,但我无法创造一个完整的解决方案。

用户创建时。它被保存到用户模型的数据库中。我想根据需要创建一个相关的人。

如果一个老师想创建帐户,他应该给一些其他类型的链接或注册表格通过谷歌OAuth和学生一个不同的。这也帮不了我。

任何形式的帮助都会很好。谢谢。

您需要删除信号并创建自己的身份验证流。

理想的方法是重写auth方法并创建自己的函数。在auth函数中,我们将获取用户类型(student, teacher),并根据用户类型创建student或teacher。

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

最新更新