Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Example of how to use Flask with requests-oauthlib to fetch a GitHub user profile using an OAuth 2 token.
from requests_oauthlib import OAuth2Session
from flask import Flask, request, redirect, session, url_for
from flask.json import jsonify
import os
app = Flask(__name__)
# This information is obtained upon registration of a new GitHub
client_id = "<your client key>"
client_secret = "<your client secret>"
authorization_base_url = ''
token_url = ''
def demo():
"""Step 1: User Authorization.
Redirect the user/resource owner to the OAuth provider (i.e. Github)
using an URL with a few key OAuth parameters.
github = OAuth2Session(client_id)
authorization_url, state = github.authorization_url(authorization_base_url)
# State is used to prevent CSRF, keep this for later.
session['oauth_state'] = state
return redirect(authorization_url)
# Step 2: User authorization, this happens on the provider.
@app.route("/callback", methods=["GET"])
def callback():
""" Step 3: Retrieving an access token.
The user has been redirected back from the provider to your registered
callback URL. With this redirection comes an authorization code included
in the redirect URL. We will use that to obtain an access token.
github = OAuth2Session(client_id, state=session['oauth_state'])
token = github.fetch_token(token_url, client_secret=client_secret,
# At this point you can fetch protected resources but lets save
# the token and show how this is done from a persisted token
# in /profile.
session['oauth_token'] = token
return redirect(url_for('.profile'))
@app.route("/profile", methods=["GET"])
def profile():
"""Fetching a protected resource using an OAuth 2 token.
github = OAuth2Session(client_id, token=session['oauth_token'])
return jsonify(github.get('').json())
if __name__ == "__main__":
# This allows us to use a plain HTTP callback
os.environ['DEBUG'] = "1"
app.secret_key = os.urandom(24)

Try it out by typing in your key and secret on line 10 & 11 then

$ virtualenv venv && source venv/bin/activate
(venv)$ pip install requests-oauthlib flask
(venv)$ python

and go to

There is a small race condition here. After the first time through callback() will get called nearly immediately and session['oauth_state'] might not be set yet. If you put a time.sleep(1) at the beginning of callback() everything is fine... but I suspect that's not the right answer...

Thanks so much for putting together this example! It really does help!




Great example can you please help me with the same example falcon that would be help full

Hello! I am trying to use your gist above, but I get the following Bad Request Error 400: - - [16/Feb/2017 18:15:19] code 400, message Bad HTTP/0.9 request type ('\x16\x03\x01\x00\xb2\x01\x00\x00\xae\x03\x03S\x1b1N\xc6\xc08\xbf\xa07\x137\x104X\xb9\x89I78;\x9eo\x89\xbe\xc9\xdb\xaa\x01d\x06i\x00\x00') - - [16/Feb/2017 18:15:19] "??SN??8??774X??I78;?o???۪di ZZ?+?/?,?0̨̩??????/5" 400 - - - [16/Feb/2017 18:15:20] "GET / HTTP/1.1" 302 - - - [16/Feb/2017 18:15:20] code 400, message Bad request syntax ("\x16\x03\x01\x00\xb2\x01\x00\x00\xae\x03\x03\\\x14K4\xa1k\x12\x90J\x18|\x82\x81\xa5Yl\xfc\x0f%\r\x1d\x9eD'\xcbD\x10\xa3\xa4 \x04y\x00\x00 ZZ\xc0+\xc0/\xc0,\xc00\xcc\xa9\xcc\xa8\xcc\x14\xcc\x13\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00/\x005\x00")
?D'?D?? y ZZ?+?/?,?0̨̩??????/5" 400 -] "??\K4?k?J|???Yl?% - - [16/Feb/2017 18:15:20] code 400, message Bad request version ('\xba\xba\xc0+\xc0/\xc0,\xc00\xcc\xa9\xcc\xa8\xcc\x14\xcc\x13\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00/\x005\x00') - - [16/Feb/2017 18:15:20] "????b??a?s?g9??2?
                                                       9?[O??R?Ց?}? ???+?/?,?0̨̩??????/5" 400 - - - [16/Feb/2017 18:15:25] code 400, message Bad request version ('zz\xc0+\xc0/\xc0,\xc00\xcc\xa9\xcc\xa8\xcc\x14\xcc\x13\xc0\x13\xc0\x14\x00\x9c\x00\x9d\x00/\x005\x00') - - [16/Feb/2017 18:15:25] "??r?????(?Uq:?<???@Kd??1??G?H
                                                                   ??{C zz?+?/?,?0̨̩??????/5" 400 -

I see the following URL in my browser with the code and state parameters in query strings:

I have been stuck on this for a long time now, can you please help me ? Here is my link to the repo:

Thank You!

Solved the error above! Notice I am using https instead of http for the localhost url. And that server was treating this as a Bad Request. Removed the s and everything worked as expected! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment