简体   繁体   English

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

[英]How to create multiple type of users using google OAuth in Django

I am working in Django and I am making a school management system where I am giving students and teachers to login and register via google OAuth .我在 Django 工作,我正在制作一个学校管理系统,让学生和教师通过 google OAuth 登录和注册。

Here are my models这是我的模型

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)
    ...

I am using google Oauth with django-allauth package to register , login users via google OAuth .我正在使用带有 django-allauth 包的 google Oauth 来注册,通过 google OAuth 登录用户。

Here I only have the ability to create only one type of user via google OAuth using signals .在这里,我只能通过 google OAuth 使用信号创建一种类型的用户。 Either I can create a student , or either I can create a teacher .要么我可以创建一个学生,要么我可以创建一个老师。 But I want to create a way so that I can register a teacher as well as a student via the same OAuth .但我想创建一种方法,以便我可以通过相同的 OAuth 注册教师和学生。 I have tried various ways and applied few logics to figure this out but I am unable to get a full fledge solution .我尝试了各种方法并应用了一些逻辑来解决这个问题,但我无法获得完整的解决方案。

Signals.py信号.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()
        ...

I am trying to find out different solutions to figure out this problem but I am unable to create a full fledge solution .我试图找出不同的解决方案来解决这个问题,但我无法创建一个完整的解决方案。

As the user is created.随着用户的创建。 It is saved to database in the User Model .它保存在 User Model 的数据库中。 I want to create a related person according to the need.我想根据需要创建一个相关的人。

If a teacher want to create acconut , he should be given some other sort of link or register form via google OAuth and for student a different one .如果教师想创建帐户,则应通过 google OAuth 为他提供某种其他类型的链接或注册表单,并为学生提供不同的链接。 This is also not helping me out.这也没有帮助我。

Any kind of help would be great .任何形式的帮助都会很棒。 Thanks.谢谢。

You need to remove signal and create your own Authentication flow.您需要删除信号并创建自己的身份验证流程。

The ideal way is to override the auth method and create your own function.理想的方法是覆盖 auth 方法并创建自己的函数。 In the auth function we will get user type (student, teacher) and we will create a Student or Teacher based on the user type.在 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)

The Serilaizer Class: Serilaizer 类:

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
    )

The registration Function:注册功能:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM