When I first started working at PMG I was immediately given the task of writing a piece of software that allowed us to upload Facebook audience data via a command-line tool. The issue? Facebook’s login uses OAuth2 authentication in order for you to access their APIs. This requires a server to handle redirect URLs which contain tokens needed to login and a web browser to accept the permissions. Both of these are very limited in a command line utility that is supposed to be small and portable.
After doing some research and Googling around I was unsuccessful in finding a solution that was worthy of implementation, so off to the drawing board I went and came up with a quick and easy solution.
For those unfamiliar with OAuth2, authentication is done in the following:
- User supplies login information and clicks login
- Facebook sends back an ‘authentication token’ to your app
- Your app sends the authentication token back to Facebook to confirm your identity
- Facebook responds with an ‘access token’ that can then be used to access their APIs
**For more info on Facebook’s OAuth2 implementation, see the ‘Facebook Access Tokens’ reference at the bottom of the post.
In this Python script, we will emulate each of the following steps above in code.
The HTTP Server
Now that we have our imports, we can begin creating our HTTP Server which consists of two parts. The HTTPServer and the BaseHTTPServerHandler. For this example we use the built in HTTP Server that Python provides for you and attach a custom Handler to it for handling callbacks from Facebook.
Lets create our HTTPServerHandler.
Now create the HTTPServer to run locally and use our handler.
Now that we have a working HTTP Server that can accept requests, we need to modify it a bit in order handle the GET request and the associated response from Facebook. First lets set up the HTTPHandler to be able to accept the Facebook App ID and App Secret (You can find both of these values in your App’s portal on the Facebook Developers page). To do this we will need to create an anonymous (Lambda) function to handle the extra arguments in the HTTPHandler’s __init__ function.
Now inject the extra arguments into the HTTPHandler.
Your HTTPServer and HTTPHandler should now look like this:
Congrats! You now have a working Python HTTP Server, but we’re not finished yet! Now we need to set up the login and redirect URLs for Facebook and actually make the request.
Facebook API Specifics
Lets create a couple variables. One global variable for the redirect URL, a local variable in HTTPHandler to hold the Authentication URL from the Facebook API, and a local variable in the get_access_token function containing the URL that enables the user to accept OAuth permissions and fire the redirect URL to our HTTP Server. Use webbrowser.open_new(url) to open a new window in the user’s default web browser.
** Note: Make sure to specify your scopes in the ACCESS_URI under “&scope=xxxxx”.
A list of available scopes can be found here.
Handling the Facebook Response
Facebook sends this token in the body of the response of your GET request as access_token=xxxxxxxxx&…. so lets create a function that can send the final request to Facebook and parse the response using the urllib.request library and use string.split to remove unnecessary information.
The last thing to do is make sure that we have our authentication code from the redirect url and get our access token from Facebook. This can be achieved by checking that the
URL contains the ‘code’ query parameter and sending this back to Facebook via our GRAPH_API_AUTH_URI variable with the auth code appended to it, then giving the response url to get_access_token_from_url() and injecting the response into the server object so we can return it after the server shuts down.
Your final HTTPHandler should look like:
And your final TokenHandler class should look like:
A link to the source code (a working implementation) can be found here.