Skip to content

Instantly share code, notes, and snippets.

@ib-lundgren
Created September 10, 2013 10:53
Show Gist options
  • Star 41 You must be signed in to star a gist
  • Fork 21 You must be signed in to fork a gist
  • Save ib-lundgren/6507798 to your computer and use it in GitHub Desktop.
Save ib-lundgren/6507798 to your computer and use it in GitHub Desktop.
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 = 'https://github.com/login/oauth/authorize'
token_url = 'https://github.com/login/oauth/access_token'
@app.route("/")
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,
authorization_response=request.url)
# 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('https://api.github.com/user').json())
if __name__ == "__main__":
# This allows us to use a plain HTTP callback
os.environ['DEBUG'] = "1"
app.secret_key = os.urandom(24)
app.run(debug=True)
@ib-lundgren
Copy link
Author

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 github_flask_oauth2.py

and go to 127.0.0.1:5000/

@friedmud
Copy link

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!

@InfinitumBITCOINS
Copy link

STRTM+TCPHTTPML://127.0.0.1:5000

@InfinitumBITCOINS
Copy link

STRTM+TCP+HTTPML://127.0.0.1:5000

@InfinitumBITCOINS
Copy link

STRTM+TCP+HTTP+ML://127.0.0.1.COM.NE:5000

@DEVANANDJALLA
Copy link

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

@ghoshabhi
Copy link

Hello! I am trying to use your gist above, but I get the following Bad Request Error 400:

127.0.0.1 - - [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')
127.0.0.1 - - [16/Feb/2017 18:15:19] "??SN??8??774X??I78;?o???۪di ZZ?+?/?,?0̨̩??????/5" 400 -
127.0.0.1 - - [16/Feb/2017 18:15:20] "GET / HTTP/1.1" 302 -
127.0.0.1 - - [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?%
127.0.0.1 - - [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')
127.0.0.1 - - [16/Feb/2017 18:15:20] "????b??a?s?g9??2?
                                                       9?[O??R?Ց?}? ???+?/?,?0̨̩??????/5" 400 -
127.0.0.1 - - [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')
127.0.0.1 - - [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:
https://127.0.0.1:5000/callback?code=41d9acb83e123cf5c3e2&state=Erq3uN7oX0APIEcQeIKhHclLU8A0CD

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

https://github.com/ghoshabhi/commit-reminder/tree/feat_oauth/commit-reminder

Thank You!

@ghoshabhi
Copy link

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! :)

@luisdoesdev
Copy link

Hahahahaah this just happened to me, took me finding this message after 40 mins of research

@jainamoswal
Copy link

Add _scheme='https' in url_for(...). This will make a URL and redirect it.
A solution while getting Bad Request when you use https instead of http.

Hope it does help you. 🙂

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