I have investigated how to use the Graph API when creating an app that uses Facebook friend information in Python, so I will summarize it. It is intended for applications that use Flask.
If you redirect to https://graph.facebook.com/oauth/authorize?client_id=****&redirect_uri=****&scope=****
and the app is not allowed, app allow Page is displayed. In Flask, you can specify this URL and do return redirect (https: // ****)
.
Parameters | Settings |
---|---|
client_id | Application ID set in Facebook Developers |
redirect_uri | URL to redirect after authentication(URI encoding required) |
scope | Permission to request |
If allowed, it will transition to the redirect destination set in redirect_uri
. The code
(authentication code) returned as a parameter at this time will be used for the next access token acquisition. Also, if any error occurs, the JSON string with ʻerror` set as shown below will be returned.
error_sample
{
"error": {
"message": "redirect_uri isn't an absolute URI. Check RFC 3986.",
"type": "OAuthException",
"code": 191,
"fbtrace_id": "XXXXXXXXXXX"
}
}
Use the verification code obtained above to go to https://graph.facebook.com/oauth/access_token?client_id=****&client_secret=****&redirect_uri=****&code=****
Access and get an access token.
Parameters | Settings |
---|---|
client_id | Application ID set in Facebook Developers |
client_secret | App secret key set in Facebook Developers |
redirect_uri | URL to redirect after authentication |
code | Authentication code obtained above(URI encoding required) |
Since the acquired data is in the form of ʻaccess_token =**** & expires =****, the value immediately after ʻaccess_token =
is fetched. In Python, it's a good idea to use something like ʻurllib2.urlopen` to get the results. The method of extraction is appropriate.
main.py
from werkzeug.urls import url_quote_plus
import urllib2
...
app_id = "xxxxxxxx"
app_secret = "xxxxxxxx"
url_redirect = url_quote_plus( "https://hogehoge.com" )
code = "xxxxxxxx"
url_token = ( "https://graph.facebook.com/oauth/access_token"
"?client_id={0}&client_secret={1}"
"&redirect_uri={2}&code={3}" )
try:
resp = urllib2.urlopen( url_token.format( app_id, app_secret, url_redirect, code ) )
data = resp.read().split('&')
access_token = data[0].strip('access_token=')
finally:
resp.close()
...
You have now obtained an access token.
It's a Flask filter that automatically gets an access token when you visit a particular page. (In the sample below, the processing when an error is returned is omitted.) By the way, is Python a decorator for such a filter? Is that so? I'm still not sure about this area.
main.py
from werkzeug.urls import url_quote_plus
from functools import wraps
from flask import Flask, request, redirect, session
import urllib2
...
domain = "https://hogehoge.com"
app_id = "xxxxxxxx"
app_secret = "xxxxxxxx"
#Generate a URL for obtaining the verification code--------------------------------------------------
def create_url_for_auth_code( path_orig ):
url_orig = url_quote_plus( domain + path_orig )
return ( "https://graph.facebook.com/oauth/authorize"
"?client_id={0}&redirect_uri={1}&scope={2}" )
#Get an access token--------------------------------------------------
def get_access_token( path_orig, code ):
url_orig = url_quote_plus( domain + path_orig )
url_token = ( "https://graph.facebook.com/oauth/access_token"
"?client_id={0}&client_secret={1}"
"&redirect_uri={2}&code={3}" )
try:
resp = urllib2.urlopen(url_token.format(app_id, app_secret, url_orig, code))
data = resp.read().split('&')
access_token = data[0].strip('access_token=')
finally:
resp.close()
return access_token
#Filter body--------------------------------------------------
def oauth_filter(f):
@wraps(f)
def wrapper(*args, **kwargs):
#If the session has an access token, return as it is
if session.has_key('access_token'):
return f(*args, **kwargs)
#If the session does not have an access token, get it by oauth authentication
code = request.args.get('code')
#Case classification according to the state of request parameters
if code is None:
#Get the code if no authorization code has been set
return redirect( create_url_for_auth_code( request.path ) )
else:
#Get an access token if an authorization code is set
session['access_token'] = get_access_token( request.path, code )
return redirect( domain + request.path )
#If the conditions are not met, exit as is
return f(*args, **kwargs)
return wrapper
...
Apply the above filter. That said, just add @oauth_filter
to the method that specifies each routing.
main.py
from flask import Flask, render_template, redirect, session
app = Flask(__name__)
...
#Does not apply to top page
@app.route('/')
def index():
return render_template("top.html")
#Applies to My Page
@app.route('/mypage')
@oauth_filter #Application! !!
def mypage():
return render_template("mypage.html")
#Remove access token from session when logging out
@app.route('/logout')
def logout():
if session.has_key( 'access_token' ):
del session['access_token']
return redirect( '/' )
...
With the above, it should work for the time being. This information was created based on a PHP sample using the Graph API below and a description of the Python login decorator.