当我通过用户名/密码进行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登录,我真的不知道用户的密码,并且提供虚假值的任何方式都会导致错误?
答案 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 {}