Получение номера телефона пользователя в приложении django из google с помощью social_core
Здравствуйте, я работаю над приложением Django, в котором есть модель Customuser, и я просто сохраняю номер телефона пользователя в модели по некоторым причинам, вот моя модель и менеджер :
class CustomUserManager(BaseUserManager):
def create_user(self, phone_number, password=None, **extra_fields):
if not phone_number:
raise ValueError('The Phone Number must be set')
user = self.model(phone_number=phone_number, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, phone_number, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
return self.create_user(phone_number, password, **extra_fields)
class CustomUser(AbstractBaseUser, PermissionsMixin):
phone_number = models.CharField(max_length=15, unique=True)
email = models.EmailField(unique=True, null=True, blank=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
score = models.PositiveIntegerField(default=10, null=True, blank=True)
objects = CustomUserManager()
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = []
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Profile.objects.get_or_create(user=self)
def add_score(self, score):
self.score += score
print(self.score)
self.save()
def decrease_score(self, score):
self.score -= score
self.save()
def generate_referral_code(self):
code_length = 19
characters = string.ascii_letters + string.digits
unique_code = ''.join(random.choice(characters) for _ in range(code_length))
while ReferralCode.objects.filter(code=unique_code).exists():
unique_code = ''.join(random.choice(characters) for _ in range(code_length))
ReferralCode.objects.create(user=self, code=unique_code)
def get_referral_code(self):
try:
return self.referralcode.code
except ReferralCode.DoesNotExist:
return None
def __str__(self):
return self.phone_number
я редактирую свой файл setting.py, чтобы иметь такой файл pipleline :
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = config("GOOGLE_CLIENT_ID")
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = config("GOOGLE_SECRET")
SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/user.phonenumbers.read',
]
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.get_username',
'social_core.pipeline.user.create_user',
'accounts.pipeline.save_profile',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details',
)
и в pipeline.py я ожидаю получить номер телефона пользователя для сохранения в базе данных, но я получаю None, также в Json файле я не вижу никакой информации о номере телефона пользователя, как я могу получить мобильный телефон? Спасибо
from .models import Profile
import json
def save_profile(backend, user, response, *args, **kwargs):
if backend.name == 'google-oauth2':
print(json.dumps(response, indent=2))
phone_number = response.get('phoneNumber')
print(f"this is phone number{phone_number}")
if phone_number:
user.phone_number = phone_number
user.email = response.get('email')
user.first_name = response.get('given_name')
user.last_name = response.get('family_name')
user.save()
Profile.objects.get_or_create(
user=user,
defaults={
'email': response.get('email'),
'first_name': response.get('given_name', ''),
'last_name': response.get('family_name', '')
}
)
Google не включает номера телефонов в ответ автоматически. Это связано с тем, что номер телефона относится к категории конфиденциальных данных и требует явного разрешения пользователя, которое часто обрабатывается отдельно.
Чтобы получить номер телефона пользователя с помощью Google OAuth, необходимо использовать другую конечную точку Google API или отдельный запрос для его получения после первоначальной аутентификации OAuth.
Вот как вы можете это сделать.
....
if backend.name == 'google-oauth2':
# Print the OAuth2 response
print(json.dumps(response, indent=2))
# Access the user's profile using the People API
access_token = response.get('access_token')
if access_token:
people_api_url = "https://people.googleapis.com/v1/people/me?personFields=phoneNumbers"
headers = {
"Authorization": f"Bearer {access_token}"
}
people_response = requests.get(people_api_url, headers=headers)
people_data = people_response.json()
# Extract the phone number from the People API response
phone_number = None
phone_numbers = people_data.get('phoneNumbers')
if phone_numbers:
phone_number = phone_numbers[0].get('value') # First phone number
print(f"this is phone number: {phone_number}")
if phone_number:
user.phone_number = phone_number
# Set other profile fields
....