Как извлечь profile_pic пользователя при входе в систему из Google

Я делаю сайт на django, у меня есть 2 метода входа. Один - стандартный вход с паролем электронной почты, а другой - вход с Google.

Я хочу, чтобы при входе пользователя из google django автоматически получал profile_pic этого пользователя и сохранял его в моей модели пользователя.

Вот мой models.py для accounts приложения

Есть ли способ достичь этого? Если есть, то предпочтительнее было бы иметь решение с использованием SCOPES

Вот мой файл settings.py для SCOPES

...
SOCIALACCOUNT_ADAPTER = 'MyApp.adapter.MySocialAccountAdapter'
SOCIALACCOUNT_QUERY_EMAIL = ACCOUNT_EMAIL_REQUIRED
SOCIALACCOUNT_LOGIN_ON_GET = True
SOCIALACCOUNT_AUTO_SIGNUP = True
SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'SCOPE': [
            'profile',
            'email',
        ],
        'AUTH_PARAMS': {
            'access_type': 'online',
        }
    }
}
...

Когда вы используете allauth в django . Вы получаете еще 3 модели. Зайдите в вашу панель администратора, в разделе Social Accounts вы найдете все эти модели.

  1. Социальный аккаунт
  2. Токен социального приложения
  3. Социальное приложение

У первого объекта (Social Account) есть поле дополнительных данных. Перейдите к любому из объектов социального аккаунта и посмотрите поле дополнительных данных . У вас будет словарь текстовой формы . В нем будет ключ profile_image (или другое название поля, возможно), который будет содержать url изображения профиля пользователя, вошедшего в систему Google .

Тогда просто сделайте простой Django ORM . profile_image = dict(SocialAccount.objects.get(id = some_id).extra_data)["profile_image"]. у вас будет url .

Я использовал DJ REST Auth Package для входа и регистрации в социальных сетях https://pypi.org/project/dj-rest-auth/

# in you setting file
# >>>  Social Authentication Settings

SOCIALACCOUNT_QUERY_EMAIL = True
SOCIALACCOUNT_ENABLED = True
LOGIN_REDIRECT_URL = "/"
ACCOUNT_EMAIL_REQUIRED=True
ACCOUNT_USERNAME_REQURIED=True
ACCOUNT_ALLOW_REGISTRATION = env.bool("ACCOUNT_ALLOW_REGISTRATION", True)
SOCIALACCOUNT_ALLOW_REGISTRATION = env.bool("SOCIALACCOUNT_ALLOW_REGISTRATION", True)
SOCIALACCOUNT_PROVIDERS = {
    'google': {
        'SCOPE': [
            'profile',
            'email',
        ],
        'AUTH_PARAMS': {
            'access_type': 'online',
        }
    }
    }
 
#I have written a method to get image from a url 
import requests
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile
def save_image_from_url(model, url, name):
    r = requests.get(url)
    img_temp = NamedTemporaryFile(delete=True)
    img_temp.write(r.content)
    img_temp.flush()
    model.name = name
    model.profile_picture.save("{}.jpg".format(model.username), File(img_temp), save=True)

# Viewset for google login
class GoogleLogin(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter
    client_class = OAuth2Client
    permission_classes = [AllowAny, ]
    callback_url = "https://developers.google.com/oauthplayground"

    def get_response(self):
        serializer_class = self.get_response_serializer()
        user = self.user
        user_extra_data = SocialAccount.objects.filter(user=self.request.user).first().extra_data
        name = user_extra_data["name"]
        profile_image_url = user_extra_data["picture"]
        if not user.profile_picture:
            save_image_from_url(user, profile_image_url, name)
        user_detail = UserSerializer(user, many=False, context={"request": self.request})
        serializer = serializer_class(instance=self.token, context={'request': self.request})
        resp = serializer.data
        resp["token"] = resp["key"]
        resp.pop("key")
        resp["user"] = user_detail.data
        response = Response(resp, status=status.HTTP_200_OK)
        return response

Вы можете попробовать получить дополнительные данные пользователя и после получить ссылку на изображение профиля:

from allauth.socialaccount.models import SocialAccount

extra_data = SocialAccount.objects.get(user=request.user).extra_data
print(extra_data['picture'])

Таким образом, вы получаете extra_data в виде словаря, поэтому вы можете просто извлечь фотографию профиля

Вернуться на верх