Django: Facebook Connect Oauth2 Permissions

ghz 12hours ago ⋅ 2 views

In my Django project, I have set up pyfacebook & django-facebookconnect to let the user login with their Fb account. However I now need to get the right permissions to get the user's data & save it in my db.

How do you add the permissions to pyfacebook & django-facebookconnect?

In facebook.init.py there is this function which I think is where I need to change the scope somehow.

Thanks for the help!

   def get_login_url(self, next=None, popup=False, canvas=True,
                      required_permissions=None):
        """
        Returns the URL that the user should be redirected to in order to login.

        next -- the URL that Facebook should redirect to after login
        required_permissions -- permission required by the application

        """
        if self.oauth2:
            args = {
                'client_id': self.app_id,
                'redirect_uri': next,
            }

            if required_permissions:
                args['scope'] = required_permissions

            if popup:
                args['display'] = 'popup'

            return self.get_graph_url('oauth/authorize', **args)
        else:
            args = {'api_key': self.api_key, 'v': '1.0'}

            if next is not None:
                args['next'] = next

            if canvas is True:
                args['canvas'] = 1

            if popup is True:
                args['popup'] = 1

            if required_permissions:
                args['req_perms'] = ",".join(required_permissions)

            if self.auth_token is not None:
                args['auth_token'] = self.auth_token

            return self.get_url('login', **args)

Update:

When you click the connect button, it passes facebookConnect:

<script type="text/javascript">
    FB_RequireFeatures(["XFBML"], function() {FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}")});

    function facebookConnect(loginForm) {
        FB.Connect.requireSession();
        FB.Facebook.get_sessionState().waitUntilReady(function(){loginForm.submit();});
    }
    function pushToFacebookFeed(data){
        if(data['success']){
            var template_data = data['template_data'];
            var template_bundle_id = data['template_bundle_id'];
            feedTheFacebook(template_data,template_bundle_id,function(){});
        } else {
            alert(data['errors']);
        }
    }
    function pushToFacebookFeedAndRedirect(data){
        if(data['success']){
            var template_data = data['template_data'];
            var template_bundle_id = data['template_bundle_id'];
            feedTheFacebook(template_data,template_bundle_id,function(){window.location.href=template_data['url'];});
        } else {
            alert(data['errors']);
        }
    }
    function pushToFacebookFeedAndReload(data){
        if(data['success']){
            var template_data = data['template_data'];
            var template_bundle_id = data['template_bundle_id'];
            feedTheFacebook(template_data,template_bundle_id,function(){window.location.reload();});
        } else {
            alert(data['errors']);
        }
    }
    function feedTheFacebook(template_data,template_bundle_id,callback) {
        FB.Connect.showFeedDialog(
            template_bundle_id,
            template_data,
            null, null, null,
            FB.RequireConnect.promptConnect,
            callback
        );
    }
</script>

xd_receiver calls:

 <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.debug.js" type="text/javascript">
</script 

Answer

To add additional Facebook permissions in your Django project with pyfacebook and django-facebookconnect, you need to modify both the get_login_url function in the pyfacebook integration and the JavaScript handling Facebook login.

Here's a step-by-step guide to add Facebook permissions to your setup:


1. Update the get_login_url function in pyfacebook

The get_login_url function generates the login URL that Facebook will redirect the user to. To add specific permissions, you need to modify the required_permissions argument that is passed into this function.

In the code snippet you've provided, you can see the get_login_url function already accepts a required_permissions parameter, which is used when constructing the login URL. You will pass the required permissions to this parameter when calling the function.

For example, you might want permissions like email, user_friends, or user_birthday to get access to the user’s email address, friends list, or birthday. These permissions are requested when the user logs in.

Here’s how you can modify it:

def get_login_url(self, next=None, popup=False, canvas=True,
                   required_permissions=None):
    """
    Returns the URL that the user should be redirected to in order to login.

    next -- the URL that Facebook should redirect to after login
    required_permissions -- permission required by the application
    """
    if self.oauth2:
        args = {
            'client_id': self.app_id,
            'redirect_uri': next,
        }

        # Add required permissions to the args
        if required_permissions:
            args['scope'] = required_permissions  # This is where permissions are added

        if popup:
            args['display'] = 'popup'

        return self.get_graph_url('oauth/authorize', **args)
    else:
        args = {'api_key': self.api_key, 'v': '1.0'}

        if next is not None:
            args['next'] = next

        if canvas is True:
            args['canvas'] = 1

        if popup is True:
            args['popup'] = 1

        # Add required permissions to the args
        if required_permissions:
            args['req_perms'] = ",".join(required_permissions)  # Add permissions here

        if self.auth_token is not None:
            args['auth_token'] = self.auth_token

        return self.get_url('login', **args)

2. Pass the Permissions When Calling the Login URL

In your Django view or the place where you are redirecting to the Facebook login URL, ensure that you pass the permissions as a list of strings. For example:

from pyfacebook import PyFacebook

facebook = PyFacebook(app_id='your_app_id', app_secret='your_app_secret')

# Define the permissions you need
permissions = ['email', 'user_friends', 'user_birthday']

# Get the login URL with the permissions
login_url = facebook.get_login_url(next='your_redirect_url', required_permissions=permissions)

This will generate a login URL with the necessary permissions. When users click on the login button, they will be prompted to grant these permissions.


3. Modify the JavaScript Code for Facebook Login

Your existing JavaScript code calls FB.Connect.requireSession() and waits for the session state before submitting the form. To request the permissions, you will need to modify the FB.Facebook.init function call, ensuring that you request the permissions explicitly.

Here’s an example of how to modify the JavaScript code to request specific permissions:

<script type="text/javascript">
    FB_RequireFeatures(["XFBML"], function() { 
        FB.Facebook.init("{{ facebook_api_key }}", "{% url facebook_xd_receiver %}");
    });

    function facebookConnect(loginForm) {
        // Specify the permissions you need
        var permissions = 'email,user_friends,user_birthday';  // List of permissions

        // Request the session with the specified permissions
        FB.Connect.requireSession(permissions);
        
        FB.Facebook.get_sessionState().waitUntilReady(function(){
            loginForm.submit();
        });
    }
</script>

In this example, the facebookConnect function now requests the email, user_friends, and user_birthday permissions.


4. Handling Permissions After Login

Once the user has granted the requested permissions, Facebook will redirect back to the URL you specified (in the next parameter). At that point, you can use the access token to make API calls to fetch the user data with the requested permissions.

For example, you can use the Facebook Graph API to fetch the user's email address:

user_data = facebook.get('/me?fields=id,name,email')

This will fetch the user’s data, including their email (if they granted the permission).


5. Save User Data in Your Database

Once you have retrieved the user data from Facebook, you can save it in your Django model. For example, if you have a UserProfile model to store Facebook user data:

from django.contrib.auth.models import User
from .models import UserProfile

def save_facebook_user_data(user_data):
    user, created = User.objects.get_or_create(username=user_data['id'])
    user_profile, created = UserProfile.objects.get_or_create(user=user)
    user_profile.name = user_data['name']
    user_profile.email = user_data['email']
    user_profile.save()

This will save the user's name and email address in the UserProfile model.


In Summary:

  1. Add permissions to the login URL by passing the required_permissions argument in the get_login_url function of pyfacebook.
  2. Modify your JavaScript to explicitly request those permissions via FB.Connect.requireSession().
  3. Handle the response after login and use the Facebook Graph API to fetch the necessary user data (email, friends, etc.).
  4. Save the data into your Django database.

This should allow you to successfully request and handle Facebook permissions in your Django project using pyfacebook and django-facebookconnect.