在 python-social-auth 中从 google 和 facebook 检索个人资料图片

Posted

技术标签:

【中文标题】在 python-social-auth 中从 google 和 facebook 检索个人资料图片【英文标题】:Retrieving profile picture from google and facebook in python-social-auth 【发布时间】:2015-06-17 00:22:24 【问题描述】:

如何通过扩展管道使用 python-social-auth 从 google 和 facebook 检索个人资料图片和出生日期?我读过我可以创建函数来执行此操作并设置它们的路径,但我不知道我必须检索的属性名称。请帮忙!

【问题讨论】:

【参考方案1】:

要从社交登录中获取头像,您需要在您的应用中创建一个 pipeline.py 文件并将此行添加到 settings.py:

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',
    'social.pipeline.user.create_user',
    'social.pipeline.social_auth.associate_user',
    'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details',
    'apps.users.pipeline.get_avatar', # This is the path of your pipeline.py
    #and get_avatar is the function.
)

稍后将此内容添加到您的 pipeline.py 文件中

def get_avatar(backend, strategy, details, response,
        user=None, *args, **kwargs):
    url = None
    if backend.name == 'facebook':
        url = "http://graph.facebook.com/%s/picture?type=large"%response['id']
    if backend.name == 'twitter':
        url = response.get('profile_image_url', '').replace('_normal','')
    if backend.name == 'google-oauth2':
        url = response['image'].get('url')
        ext = url.split('.')[-1]
    if url:
        user.avatar = url
        user.save()

【讨论】:

访问graph.facebook.com时一定要使用HTTPS而不是HTTP【参考方案2】:

这是我用来为 Facebook 保存图片的方法:

def save_profile_picture(backend, user, response, details,
                         is_new=False,*args,**kwargs):

    if backend.__class__.__name__ == 'FacebookOAuth2':
        up = UserProperties.objects.get_or_create(user=user) #RETURNS TUPLE (instance, created(boolean))
        if not up[0].photo:
            url = 'http://graph.facebook.com/0/picture'.format(response['id'])
            response = urllib.request.urlopen(url)
            io = BytesIO(response.read())
            up[0].photo.save('profile_pic_.jpg'.format(user.pk), File(io))
            up[0].save() 

将此函数保存到文件中,例如 pipelines.py,然后将该函数添加到设置中的 SOCIAL_AUTH_PIPELINE。

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',
    'social.pipeline.social_auth.associate_by_email', 
    'social.pipeline.user.create_user',
    'social.pipeline.social_auth.associate_user',
    'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details',
    'projects.pipeline.save_profile_picture', #save facebook profile image,
)

对于 Facebook,您需要创建自己的 Facebook 应用。您只能从授予您权限的用户那里检索信息和图片。同样的规则或多或少适用于谷歌。阅读他们的 API 文档了解更多详情。

【讨论】:

所以我的理解是,我必须找到一个 URL,Google+ 在其上提供其图像并使用它来检索个人资料图片,然后覆盖我的管道。我做对了吗? 是的。阅读他们的文档以获取更多详细信息。您需要在正确的位置将函数添加到管道中以获得所需的行为。对于投反对票的人:我给出了一个很好的答案如何开始。您不能指望人们为其他人编写整个程序,而是给出使 OP 走上正轨的答案,就像这里的情况一样。不幸的是,这种消极情绪在这里很猖獗。 我还有一个疑问,我有一个自定义模型,它继承了 Django.contrib.author 的用户模型,然后是 DOB 和个人资料图片的另外两个字段。当我使用 OAuth2 登录 Google 时,管理面板中的 django.contrib.auth.user 得到了它的值,但我的自定义模型没有与它一对一地链接。关于我如何能够做到这一点的任何建议? 看来google现在需要一个api请求GET https://www.googleapis.com/plus/v1/people/userId,它将返回一个包含请求图像的json响应。看到这个answer 访问graph.facebook.com时一定要使用HTTPS而不是HTTP【参考方案3】:

上述答案可能不起作用(它对我不起作用),因为没有 accesstoken,facebook 个人资料 URL 不再起作用。以下答案对我有用。

def save_profile(backend, user, response, is_new=False, *args, **kwargs):
    if is_new and backend.name == "facebook":
        # The main part is how to get the profile picture URL and then do what you need to do
        Profile.objects.filter(owner=user).update(
            imageUrl='https://graph.facebook.com/0/picture/?type=large&access_token=1'.format(response['id'],
                                                                                                  response[
                                                                                                      'access_token']))
    elif backend.name == 'google-oauth2':
        if is_new and response.get('picture'):
            Profile.objects.filter(owner=user).update(imageUrl=response['picture'])

在setting.py中添加到管道中,

SOCIAL_AUTH_PIPELINE+ = ('<full_path>.save_profile')

【讨论】:

【参考方案4】:

只是为了扩展萨达特的答案,它非常适合保存网址。如果您想将实际图像从 url 保存到 django imagefield,则需要执行以下操作:

import requests
from io import BytesIO
from django.core import files

def save_profile(backend, user, response, is_new=False, *args, **kwargs):
if is_new and backend.name == "facebook":
    
    picture_url='https://graph.facebook.com/0/picture/?type=large&access_token=1'.format(response['id'],
                                                                                              response[
                                                                                                  'access_token']))   
    file_name = f"uuid.uuid4().jpeg"
            resp = requests.get(picture_url)
            if resp.status_code == requests.codes.ok:
                fp = BytesIO()
                fp.write(resp.content)
  
                profile.image.save(file_name, files.File(fp))
                profile.save()

【讨论】:

以上是关于在 python-social-auth 中从 google 和 facebook 检索个人资料图片的主要内容,如果未能解决你的问题,请参考以下文章

使用 django python-social-auth 重定向后会话值丢失

html Python-social-auth:登录后重定向(包括GET参数)

在 ubuntu 操作系统中从单声道 P/Invoke g++

python Python,Facebook,python-social-auth:获取Facebook好友列表及其姓名,位置,个人资料图片和个人资料页面

python-social-auth with Django: ImportError: No module named 'social_django'

第三方登陆组件