Социальный вход Аллаута с DRF JWT
Я использую DRF, DRF-JWT, Allauth и Res-auth и djangorestframework-jwt-refresh-token в своем приложении Django.
У меня есть пользовательский регистратор сериализатора JWT для сбора дополнительной информации о пользователе, а также для создания и создания токена обновления, который используется для обновления устаревших токенов JWT. Мы работаем с бэкэндом и ios Application без проблем при регистрации по электронной почте. Сейчас я пытаюсь реализовать JWT с помощью элемента allouth sociallogin, в частности facebook, в качестве поставщика.
Я могу создать токен обновления для пользователя Facebook, переопределив DefaultSocialAccountAdapter, но я пытаюсь вернуть ответ Json с JWT с указанным токеном обновления на мобильный клиент.
Это создает токен обновления:
class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
def save_user(self, request, sociallogin, form):
user = super(CustomSocialAccountAdapter, self).save_user(request, sociallogin, form)
app = 'users'
user.refresh_tokens.create(app=app)
return user
Я могу создать JWT вручную с помощью этого:
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
Мне просто трудно собрать все это вместе, должен ли я переопределить адаптер или использовать сигнал pre_social_login.
Любые указатели приветствуются.
1 ответ
Я пошел со следующим, чтобы вернуть долгоживущий токен обновления и URL-адрес аватара в логине Facebook:
class CustomJWTSerializer(JWTSerializer):
"""
OVERIDE JWTSerializer Base Serializer for JWT authentication to
add long refresh_token to returned JSON
"""
refresh_token = serializers.CharField()
avatar_url = serializers.CharField()
class FacebookLogin(SocialLoginView):
adapter_class = FacebookOAuth2Adapter
def process_login(self):
get_adapter(self.request).login(self.request, self.user)
user = self.request.user
app = 'users'
try:
refresh_token = user.refresh_tokens.get(app=app).key
except RefreshToken.DoesNotExist:
refresh_token = None
if refresh_token == None:
app = 'users'
user.refresh_tokens.create(
app=app
)
preferred_avatar_size_pixels = 256
facebook_social_account = SocialAccount.objects.get(user=user)
uid = facebook_social_account.uid
picture_url = "http://graph.facebook.com/{0}/picture?width={1}&height={1}".format(
uid, preferred_avatar_size_pixels)
profile = Profile(user=user, avatar_url=picture_url)
profile.save()
def get_response(self):
serializer_class = CustomJWTSerializer
refresh_token = RefreshToken.objects.get(user=self.user)
profile = Profile.objects.get(user=self.user)
avatar_url = profile.avatar_url
if getattr(settings, 'REST_USE_JWT', False):
data = {
'user': self.user,
'token': self.token,
'refresh_token': refresh_token,
'avatar_url': avatar_url
}
serializer = serializer_class(instance=data,
context={'request': self.request})
else:
serializer = serializer_class(instance=self.token,
context={'request': self.request})
return Response(serializer.data, status=status.HTTP_200_OK)
Я не знаю, был ли это правильный способ сделать это, но пока это работает.