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

Posted

技术标签:

【中文标题】使用 Google Auth 时对 Django Rest Framework 进行身份验证【英文标题】:Authenticate Django Rest Framework when using Google Auth 【发布时间】:2019-04-02 18:57:19 【问题描述】:

当我通过用户名/密码进行 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='No active account found with the given credentials', code='invalid')]

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

【问题讨论】:

【参考方案1】:

看起来像块:

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

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

【讨论】:

我认为这已经完成了? 'django.contrib.auth.middleware.AuthenticationMiddleware' 上面的问题是通过 DRF validate() 方法登录用户。 啊,我误会了,一会儿删掉【参考方案2】:

我能弄清楚如何做到这一点的唯一方法是覆盖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 

【讨论】:

所以为了清楚起见,您只是想通过他们的电子邮件对某人进行身份验证,对吗?

以上是关于使用 Google Auth 时对 Django Rest Framework 进行身份验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 django-rest-auth 和 allauth 进行 Google 身份验证

使用现有的 django.contrib.auth.forms 实现 Django Simple Captcha

django-rest-auth + django-allauth + angular2

Wagtail Cms是否支持Google登录和用户登录添加会话

如何使用颤振在 django 中进行 google、facebook 身份验证

如何在 django 模板中使用嵌套的 forloop 生成表时对 t 行进行编号