Skip to content

Instantly share code, notes, and snippets.

@HuakunShen
Last active June 19, 2021 21:27
Show Gist options
  • Save HuakunShen/1840f8992ea2a282d2cfe32b2cda9070 to your computer and use it in GitHub Desktop.
Save HuakunShen/1840f8992ea2a282d2cfe32b2cda9070 to your computer and use it in GitHub Desktop.
GitHub OAuth 2.0 Web Flow

GitHub OAuth 2.0 Web Flow

https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#web-application-flow

This repo contains a simple web app demonstrating how GitHub OAuth App work in Web Flow.

The web server is written in Flask.

Make sure flask server is installed.

pip install Flask

To run it, you have to register a GitHub OAuth App.

Open server.py, fill in the variable names at the top (client id, client secret).

Run server.py, python server.py, and access http://localhost:8080.

Go to the root page (http://localhost:8080), enter your GitHub usename and proceed.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GitHub OAuth 2.0 Web Flow</title>
</head>
<body>
<h1>GitHub OAuth 2.0 Web Flow</h1>
<form action="" method="post">
<input name="username" type="text" placeholder="GitHub Username" />
<button type="submit">Submit</button>
</form>
</body>
</html>
import os
import json
import requests
from urllib.parse import urlparse
from flask import Flask, redirect, request, render_template, jsonify
app = Flask(__name__, template_folder=os.path.dirname(
os.path.abspath(__file__)))
CLIENT_ID = "Enter your client id"
CLIENT_SECRET = "Enter your client secret"
SCOPE = "user" # use whatever scope you need
STATE = "state-prevent-csrf"
REDIRECT_URI = "http://localhost:8080/auth/github"
ALLOW_SIGNUP = "true"
@app.route('/', methods=['post', 'get'])
def index():
if request.method == 'GET':
return render_template("index.html")
elif request.method == 'POST':
username = request.form.get('username')
return redirect(f'https://github.com/login/oauth/authorize?login={username}&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&allow_signup={ALLOW_SIGNUP}&state={STATE}&scope={SCOPE}')
else:
return '404', 404
@app.route('/auth/github')
def github_auth():
authorization_code = request.args.get('code')
state = request.args.get('state')
print(authorization_code)
print(state)
if state != STATE:
return "state doesn't match", 400
if authorization_code is None:
return 'authorization code not available', 400
access_token_url = f'https://github.com/login/oauth/access_token?client_id={CLIENT_ID}&client_secret={CLIENT_SECRET}&code={authorization_code}'
print(access_token_url)
res = requests.post(access_token_url, headers={
'Accept': 'application/json'})
data = res.json()
user_data = None
if 'access_token' in data.keys():
res = requests.get(
"https://api.github.com/user", headers={'Authorization': 'token ' + data['access_token']})
user_data = res.json()
return render_template("user-info.html", data=data, user_info=json.dumps(user_data, indent=2))
if __name__ == '__main__':
app.run('localhost', 8080, debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>GitHub OAuth 2.0 Web Flow</title>
</head>
<body>
<h1>GitHub OAuth 2.0 Web Flow</h1>
<a href="/">Home</a>
{% for key, value in data.items() %}
<p><strong>{{key}}:</strong> {{value}}</p>
{% endfor %}
<h2>User Info</h2>
<pre>{{user_info}}</pre>
<script></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment