Как в Django реализовать заполнение профиля пользователя через Google

от автора

Эта статья продолжает пост, в котором был рассмотрен один из алгоритмов аутентификации пользователя через платформу Google. Сейчас мы дополним ее механизмом заполнения профиля пользователя данными из Google-аккаунта. Хотелось бы подчеркнуть, что в обеих статьях рассматривается только один из алгоритмов. Он, на мой взгляд, наиболее понятен для начинающих разработчиков, хотя существуют и другие способы. О них можно узнать из документации Django.

Проведя аутентификацию через Google, мы получили только стандартные данные — идентификатор и имя пользователя. Но можно получить и другие, в частности, email, возраст, информацию о себе и т.д.

Реализуем в проекте собственный сервис (pipeline) и добавим в пакет приложения authapp соответствующий модуль (pipeline.py):

Код модуля pipeline.py:

from datetime import datetime from urllib.parse import urlencode from urllib.parse import urlunparse from django.utils import timezone from social_core.exceptions import AuthForbidden import requests from .models import TravelUser, TravelUserProfile   def save_user_profile(backend, user, response, *args, **kwargs):     if not isinstance(user, TravelUser):         return      if backend.name != 'google-oauth2':         return      api_url = urlunparse((         'https',         'people.googleapis.com',         '/v1/people/me',         None,         urlencode({             'personFields': 'genders,birthdays,biographies',             'access_token': response['access_token']         }),         None     ))      resp = requests.get(api_url)      if resp.status_code != 200:         print(f"Ошибка при получении данных от Google API: {resp.status_code} - {resp.text}")         return      data = resp.json()     try:         user_profile = user.traveluserprofile     except TravelUserProfile.DoesNotExist:         user_profile = TravelUserProfile.objects.create(user=user)      if 'genders' in data and data['genders']:         gender_data = data['genders'][0]         if 'value' in gender_data:             if gender_data['value'].lower() == 'male':                 user_profile.gender = TravelUserProfile.MALE             elif gender_data['value'].lower() == 'female':                 user_profile.gender = TravelUserProfile.FEMALE      if 'biographies' in data and data['biographies']:         about_me_data = data['biographies'][0]         if 'value' in about_me_data:             user_profile.aboutMe = about_me_data['value'][:512]      if 'birthdays' in data and data['birthdays']:         birthday_data = data['birthdays'][0]         if 'date' in birthday_data:             bdate_dict = birthday_data['date']             try:                 year = bdate_dict.get('year')                 if year:                     current_year = timezone.now().date().year                     age = current_year - year                      if age < 18:                         user.delete()                         raise AuthForbidden('social_core.backends.google.GoogleOAuth2')                      user.age = age             except ValueError as e:                 print(f"Ошибка парсинга даты рождения: {e}")                 pass      user_profile.save()     user.save()

 Разберем некоторые важные моменты.

Первым делом мы проверяем, что для аутентификации применяется бэкенд ‘google-oauth2’:

if backend.name != 'google-oauth2':     return

Теперь нам нужно сформировать API-URL, через который мы выполним извлечение необходимых параметров из нашего аккаунта:

api_url = urlunparse((     'https',     'people.googleapis.com',     '/v1/people/me',     None,     urlencode({         'personFields': 'genders,birthdays,biographies',         'access_token': response['access_token']     }),     None ))

Выполним запрос к этому URL, заодно проверим, что код ответа 200 (все OK):

resp = requests.get(api_url)  if resp.status_code != 200:     print(f"Ошибка при получении данных от Google API: {resp.status_code} - {resp.text}")     return

Получим ответ, из которого извлечем нужный нам словарь с параметрами:

data = resp.json()

Выполним парсинг необходимых параметров – пола, данных о себе и дате рождения (с вычислением возраста). Разумеется, эти данные должны быть заполнены в вашем Google-профиле:

if 'genders' in data and data['genders']:     gender_data = data['genders'][0]     if 'value' in gender_data:         if gender_data['value'].lower() == 'male':             user_profile.gender = TravelUserProfile.MALE         elif gender_data['value'].lower() == 'female':             user_profile.gender = TravelUserProfile.FEMALE  if 'biographies' in data and data['biographies']:     about_me_data = data['biographies'][0]     if 'value' in about_me_data:         user_profile.aboutMe = about_me_data['value'][:512]  if 'birthdays' in data and data['birthdays']:     birthday_data = data['birthdays'][0]     if 'date' in birthday_data:         bdate_dict = birthday_data['date']         try:             year = bdate_dict.get('year')             if year:                 current_year = timezone.now().date().year                 age = current_year - year                  if age < 18:                     user.delete()                     raise AuthForbidden('social_core.backends.google.GoogleOAuth2')                  user.age = age         except ValueError as e:             print(f"Ошибка парсинга даты рождения: {e}")             pass 

 И сохраним данные в профиле:

user_profile.save() user.save()

Для нашего нового сервиса необходимо прописать настройки в модуле settings.py:

SOCIAL_AUTH_PIPELINE = (     'social_core.pipeline.social_auth.social_details',     'social_core.pipeline.social_auth.social_uid',     'social_core.pipeline.social_auth.auth_allowed',     'social_core.pipeline.social_auth.social_user',     'social_core.pipeline.user.create_user',     'authapp.pipeline.save_user_profile',     'social_core.pipeline.social_auth.associate_user',     'social_core.pipeline.social_auth.load_extra_data',     'social_core.pipeline.user.user_details', )

Если после этого вы запустите проект и сделаете аутентификацию через Google, то увидите ошибку:

"message": "People API has not been used in project 847071034656 before or it is disabled. Enable it by visiting

https://console.developers.google.com/apis/api/people.googleapis.com/overview?project=847071034656

then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",

Нужно перейти по указанной ссылке и нажать кнопку Enable для установления разрешения на обмен информацией.

После этого можно запустить проект и проверить, что профиль действительно заполняется.

P.S. Я создал небольшой Django-проект, на котором вы можете проверить работоспособность механизма. Скачать его можно здесь. Также приглашаю вас в мой ТГ-канал, где я размещаю авторские материалы по Python, обсуждаем вопросы с собесов и проводим другие активности.


ссылка на оригинал статьи https://habr.com/ru/articles/923360/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *