August 2018: Please note that this post was written for an old version of Django. It is left here for historical purposes only.
Recently we had to add support for social networks login to an application we are developing and we chose django-social-auth to work with. It is a well documented and easy to use django application for authentication.
But we wanted to do more than just authenticating the user, we wanted to get extra data like the profile picture, gender, etc. Fortunately django-social-auth has an useful pipeline that you can expand to fulfill this kind of tasks. I will explain briefly how to achieve this. I will assume you already have authentication working which is very well explained in the documentation.
First of all, we should define the pipeline in our settings.py like this:
SOCIAL_AUTH_PIPELINE = ('social_auth.backends.pipeline.social.social_auth_user','social_auth.backends.pipeline.associate.associate_by_email','social_auth.backends.pipeline.user.get_username','social_auth.backends.pipeline.user.create_user','social_auth.backends.pipeline.social.associate_user','social_auth.backends.pipeline.user.update_user_details','auth_pipelines.pipelines.get_user_avatar',)
All the items in the pipeline except the last one are from django-social-auth and are part of the original pipeline, and the last one is the one in charge of getting the avatar and should be coded.
After we have our pipeline ready we need to implement the function that looks like this:
def get_user_avatar(backend, details, response, social_user, uid,user, *args, **kwargs):url = Noneif backend.__class__ == FacebookBackend:url = "https://graph.facebook.com/%s/picture?type=large" % response['id']elif backend.__class__ == TwitterBackend:url = response.get('profile_image_url', '').replace('_normal', '')if url:profile = user.get_profile()avatar = urlopen(url).read()fout = open(filepath, "wb") #filepath is where to save the imagefout.write(avatar)fout.close()profile.photo = url_to_image # depends on where you saved itprofile.save()
If you want to extend the functionality of getting the avatar from others social networks you should check the backend and get the image url accordingly.
On the other hand, if you want to get another kind of information like gender or age you should define another pipeline item and do something like we did above.
That's pretty much everything. Happy coding!