Created
August 28, 2015 17:10
-
-
Save theycallmeswift/dfd62ba2b7548e8f6ce8 to your computer and use it in GitHub Desktop.
A sample implementation of My MLH using Flask. Requirements: Python 2.7, Flask, and Requests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask import Flask, jsonify, make_response, redirect, request | |
import urllib | |
import requests | |
app = Flask(__name__) | |
# Config | |
callback = 'http://localhost:5000/auth/mlh/callback' | |
client_id = '[ INSERT CLIENT ID ]' | |
client_secret = '[ INSERT CLIENT SECRET ]' | |
# Helpers | |
def fetch_user(access_token): | |
base_url = "https://my.mlh.io/api/v1/user" | |
qs = urllib.urlencode({'access_token': access_token}) | |
# Tokens don't expire, but users can reset them, so best to do some error | |
# handling here too. | |
return requests.get(base_url + '?' + qs).json() | |
# Routes | |
@app.route('/') | |
def index(): | |
return "<a href='/auth/mlh'>Login with MLH</a>" | |
@app.route('/auth/mlh') | |
def auth_with_provider(): | |
# Step 1: Request an Authorization Code from My MLH by directing a user to | |
# your app's authorize page. | |
base_url = "https://my.mlh.io/oauth/authorize" | |
qs = urllib.urlencode({ | |
'client_id': client_id, | |
'redirect_uri': callback, | |
'response_type': 'code' | |
}) | |
return redirect(base_url + '?' + qs) | |
@app.route('/auth/mlh/callback', methods=['GET', 'POST']) | |
def auth_with_provider_callback(): | |
# Step 2: Assuming the user clicked authorize, we should get an Authorization | |
# Code which we can now exchange for an access token. | |
code = request.args.get('code') | |
base_url = "https://my.mlh.io/oauth/token" | |
body = { | |
'client_id': client_id, | |
'client_secret': client_secret, | |
'code': code, | |
'grant_type': 'authorization_code', | |
'redirect_uri': callback | |
} | |
if not code: | |
# If somehow we got here without a code, tell the user it's an invalid request | |
return make_response('Error: No code found', 400) | |
resp = requests.post(base_url, json=body) | |
if resp.status_code == requests.codes.ok: | |
# Step 3: Now we should have an access token which we can use to get the | |
# current user's profile information. In a production app you would | |
# create a user and save it to your database at this point. | |
user = fetch_user(resp.json()['access_token']) | |
return jsonify(user) | |
else: | |
# Really you should have better error handling | |
return make_response('Error: Internal Server Error', 500) | |
if __name__ == '__main__': | |
app.run(debug=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment