When I first started implementing OAuth, I thought it would be difficult, but I realized with all the libraries and documentation now a days, implementing would be very manageable. While I thought using libraries to help would speed up the implementation — in hindsight, implementing OAuth with rauth, a Python OAuth wrapper library, unnecessarily abstracted away both logic and understanding.
OAuth consists of 5 components:
- Present user to webpage
- Page redirect to facebook
- Get code
- Exchange code for an access token that you store
- Use that access token to access user data with API
The complications usually lie in the details. The common problems I ran into were:
1. This authorization code has already been used.
I was calling the authorization code twice, when I should have exchanged the code for an auth token and called the auth token twice.
2. Incorrect access token
I had already exchanged the code for a token with rauth, and was trying to do it manually:
def facebook_authorized(): code = request.args.get('code') if not code: return redirect(url_for('index')) data = dict(code=code, redirect_uri=get_redirect_uri()) # rauth request fb_session = get_facebook().get_auth_session( data=data, decoder=lambda x: json.loads(x.decode()) ) me = fb_session.get('me?fields=id,email,name').json() # manual request res = requests.get('https://graph.facebook.com/oauth/access_token', params=token_params) access_token = res.content.access.token
To get the access code from rauth, I can use
access_token = fb_session.access_token
Documentation is better than StackOverflow
]With documentation, you can figure out the first principles by yourself and troubleshoot your specific use case. Sometimes, StackOverflow can shortcut this for you, but more often than not you’ll solve the symptom but not the problem.
Don’t overoptimize too early.
I made the mistake of abstracting my OAuth functions into classes and started running into errors — the abstracted data structures made it difficult to pinpoint what the problem actually was.
Understand principles before jumping to the code
Rather than copying and pasting coding that you don’t understand, first understand how it works manually (i.e. the 5 steps above) and try to replicate that yourself.