使用Google Auth时对Django Rest Framework进行身份验证

时间:2018-10-29 19:18:03

标签: python django python-3.x django-rest-framework jwt

当我通过用户名/密码进行JWT身份验证时,它的工作方式如下:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

'''post looks like: <QueryDict: {
    'csrfmiddlewaretoken': ['Pd1mjNUXEdeiObEGOg8oNeqU18nwMVkSu8C29e0POGKwa2kY3yHiXk6hOEzuatMg'], 
    'email': ['tom@gmail.com'], 
    'password': ['xyxyzuzu'], 
    'evaluateUsername': ['Login']
}>'''

tokens = MyTokenObtainPairSerializer().validate(request.POST)
request.session["accessToken"] = tokens["access"]
request.session["refreshToken"] = tokens["refresh"]

足够容易。但是,如果我使用的是Google登录名,则无权访问用户的电子邮件或密码。我可以通过以下方式轻松获取电子邮件:

if not request.POST.get('email'):
    request.POST._mutable = True
    request.POST['email'] = user.email
    # request.POST['password'] = '********' # placeholder
    request.POST._mutable = False

但是在Django authenticate(user, password)上它仍然会失败,因此出现以下错误:

  

rest_framework.exceptions.ValidationError:[ErrorDetail(string ='未找到具有给定凭据的活动帐户',代码='无效')]

我将如何解决这个问题,因为如果用户使用Google Auth登录,我真的不知道用户的密码,并且提供虚假值的任何方式都会导致错误?

2 个答案:

答案 0 :(得分:0)

看起来像一个方块:

if not request.POST.get('email'):
    request.POST._mutable = True
    request.POST['email'] = user.email
    # request.POST['password'] = '********' # placeholder
    request.POST._mutable = False

已经具有用户sessiontoken,因此对于不可用的端点,可以在SesssionAuthenticationMiddleware文件中启用settings.py

答案 1 :(得分:0)

我能弄清楚如何做到这一点的唯一方法是覆盖validate方法。例如:

class TokenObtainSerializer(serializers.Serializer):
    username_field = User.USERNAME_FIELD

    def __init__(self, *args, **kwargs):
        super(TokenObtainSerializer, self).__init__(*args, **kwargs)
        self.fields[self.username_field] = serializers.CharField()
        self.fields['password'] = PasswordField()

    def validate(self, attrs):
        """
        Overwrite the `validate` method because with Google Auth we don't have a password.
        """

        email = attrs[self.username_field]
        self.user = User.objects.get(email=email)
        return {}