【问题标题】:Authenticate Django Rest Framework when using Google Auth使用 Google Auth 时对 Django Rest Framework 进行身份验证
【发布时间】: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 登录,我真的不知道用户的密码,并且任何提供虚假值的方式都会导致错误?

【问题讨论】:

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


    【解决方案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 {}
    

    【讨论】:

    • 所以为了清楚起见,您只是想通过他们的电子邮件对某人进行身份验证,对吗?
    猜你喜欢
    • 2021-01-19
    • 2017-06-05
    • 2019-05-18
    • 1970-01-01
    • 2019-07-28
    • 2015-06-02
    • 2013-05-03
    • 2019-01-01
    • 1970-01-01
    相关资源
    最近更新 更多