2

вот мой трубопровод в settings.py:Facebook не возвращается по электронной почте Python Social Auth

SOCIAL_AUTH_PIPELINE = (
    'social.pipeline.social_auth.social_details', 
    'social.pipeline.social_auth.social_uid', 
    'social.pipeline.social_auth.auth_allowed', 
    'social.pipeline.social_auth.social_user', 
    'social.pipeline.user.get_username', 
    'accounts.pipeline.create_user', 
    'accounts.pipeline.update_user_social_data', 
    # 'social.pipeline.user.create_user', 
    'social.pipeline.social_auth.associate_user', 
    'social.pipeline.social_auth.load_extra_data', 
    'social.pipeline.user.user_details', 
) 

вместе с этой линии:

SOCIAL_AUTH_FACEBOOK_SCOPE = ['email'] 

Я попытался это так:

FACEBOOK_EXTENDED_PERMISSIONS = ['email'] 

и в моем pipeline.py:

def create_user(strategy, details, user=None, *args, **kwargs): 
    if user: 
     return { 
      'is_new': False 
     } 

    fields = dict((name, kwargs.get(name) or details.get(name)) 
        for name in strategy.setting('USER_FIELDS', 
               USER_FIELDS)) 

    if not fields: 
     return 

    if strategy.session_get('signup') == 'UserType1': 
     user1 = UserType1.objects.create_user(username=fields.get('username')) 
     user1.user_type = User.USERTYPE1 
     user1.save() 

     return { 
      'is_new': True, 
      'user': user1 
     } 

    elif strategy.session_get('signup') == 'UserType2': 
     user2 = UserType2.objects.create_user(username=fields.get('username')) 
     user2.user_type = User.USERTYPE2 
     user2.save() 

     return { 
      'is_new': True, 
      'user': user2 
     } 


def update_user_social_data(strategy, *args, **kwargs): 
    if not kwargs['is_new']: 
     return 

    full_name = '' 
    backend = kwargs['backend'] 

    user = kwargs['user'] 

    full_name = kwargs['response'].get('name') 
    user.full_name = full_name 

    email = kwargs['response'].get('email') 
    user.email = email 

    user.save() 

Однако kwargs['response'].get('name') возвращает полное имя пользователя, но kwargs['response'].get('email') всегда отсутствует. Когда я делаю print kwargs['response'], он показывает только uid и имя пользователя, поэтому Facebook не возвращает адрес электронной почты пользователя. Как преодолеть это? Благодаря!

ответ

3

Видимо вам нужно сделать еще один запрос, как следующий (опять же в социальном трубопроводе):

def update_user_social_data(strategy, *args, **kwargs): 
    if not kwargs['is_new']: 
     return 

    user = kwargs['user'] 

    fbuid = kwargs['response']['id'] 
    access_token = kwargs['response']['access_token'] 

    url = u'https://graph.facebook.com/{0}/' \ 
      u'?fields=email' \ 
      u'&access_token={1}'.format(
     fbuid, 
     access_token, 
    ) 

    request = urllib2.Request(url) 
    email = json.loads(urllib2.urlopen(request).read()).get('email') 

    user.email = email 
    user.save() 
+0

это может не работать все время, так как электронная почта не является обязательным для заполнения аккаунтом Facebook. Для создания учетной записи Facebook вам необходим один, но не обязательно как адрес электронной почты, так и мобильный. –

+1

Возможно, пользователь решит не отдать свой адрес электронной почты в диалоговом окне доступа к разрешению, вы можете проверить kwargs ['response'] [ given_scopes '] и kwargs [' response '] [' denied_scopes '] для ссылок. Чтобы снова запросить пользователя для отправки по электронной почте, вы можете добавить SOCIAL_AUTH_FACEBOOK_AUTH_EXTRA_ARGUMENTS = {'auth_type': 'rerequest'} в settings.py. Ссылка: [Re-ask for Declined Permissions] (https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow) – Shihwei

10

Я думаю, что это может произойти из-за изменений в графике API v2.4 Facebook.

В предыдущих версиях API, добавляя

SOCIAL_AUTH_FACEBOOK_SCOPE = ['email'] 

позволит вам получить электронную почту пользователя facebook в. Теперь этого недостаточно, и kwargs['response'].get('email') пуст.

Однако, как объяснено в python social auth issue 675, также добавив в

SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { 
    'fields': 'id,name,email', 
} 

с вашими настройками, кажется, чтобы обойти эту проблему, и вы можете получить по электронной почте пользователя снова.

+1

Это правда, что это произошло из-за изменений в API, но это не помогло мне. Мне пришлось сделать еще один запрос, как я написал в своем ответе. Спасибо в любом случае, я ценю это. –