This directory contains the GitHub OAuth integration implementation, demonstrating how to use the composable OAuth interface to authenticate with GitHub API.
Important: GitHub OAuth Apps support only one authorization callback URL. If you have an existing OAuth App for production, you'll need to create a separate OAuth App for local development.
- Log in to GitHub and go to Settings > Developer settings > OAuth Apps
- Click New OAuth App
- Fill in the required fields:
- Application name: Your application name (e.g., "My App - Local Development")
- Homepage URL: Your application homepage (can be
http://localhostfor testing) - Authorization callback URL:
http://localhost:3000/auth_flow(or any port you prefer) - Note: This must be the exact callback URL you'll use locally. GitHub OAuth Apps do not support multiple callback URLs.
- Click Register application
- Copy the Client ID and generate a Client Secret
Why a separate app?: Unlike GitHub Apps, OAuth Apps are limited to a single callback URL. If your redirect_uri doesn't match exactly (including host, port, and path), the authorization will fail. For local development, create a dedicated OAuth App with a localhost callback URL.
Create github/secrets/config.json with your GitHub OAuth credentials:
{
"client_id": "your-github-client-id",
"client_secret": "your-github-client-secret",
"redirect_uri": "http://localhost:3000/auth_flow",
"scopes": [
"repo",
"read:org",
"read:repo_hook",
"read:user",
"read:project",
"read:discussion",
"workflow"
]
}Note: The scopes listed above are the default scopes. You can modify them based on your needs. See GitHub OAuth Scopes for available scopes.
Execute the OAuth flow script to obtain access tokens:
python github/oauth_flow.pyThis will:
- Open your browser to the GitHub authorization page
- Start a local HTTP server on the port specified in your redirect_uri to handle the callback
- Exchange the authorization code for access tokens
- Save tokens to
github/secrets/tokens.json
Once tokens are obtained, you can use them to make authenticated API requests:
python github/get.pyThis script demonstrates fetching user information and repositories from the GitHub API using the stored access token.
oauth_definition.py-GitHubOAuthDefinitionclass extendingBaseOAuthDefinitionoauth_flow.py- Interactive CLI script for OAuth flowget.py- POC script demonstrating API access with tokenssecrets/config.json- OAuth client credentials (create this file)secrets/tokens.json- Access tokens (generated by oauth_flow.py)
- Authorization:
https://github.com/login/oauth/authorize - Token Exchange:
https://github.com/login/oauth/access_token - API Base:
https://api.github.com/
GitHub uses form-encoded data for token exchange:
- Content-Type:
application/x-www-form-urlencoded - Accept:
application/json(to receive JSON response) - Request body is URL-encoded form data
Default scopes included:
repo- Full control of private repositoriesread:org- Read org and team membershipread:repo_hook- Read repository hooksread:user- Read user profile dataread:project- Read project dataread:discussion- Read discussion dataworkflow- Update GitHub Action workflows
See GitHub OAuth Scopes for the complete list.
If the specified port is already in use, change the redirect_uri in config.json to use a different port (e.g., http://localhost:9001/auth_flow). Make sure the same redirect URI is registered in your GitHub OAuth App settings.
- Verify your
client_idandclient_secretare correct - Ensure the
redirect_uriin config matches exactly what's registered in GitHub OAuth App - Check that your OAuth App is active and not suspended
- Verify the scopes requested are allowed for your OAuth App
GitHub tokens don't expire by default unless revoked. If you receive authentication errors:
- Check if the token was revoked in GitHub settings
- Run
oauth_flow.pyagain to obtain a new token
Critical: GitHub OAuth Apps support only one callback URL, and it must match exactly (host, port, and path).
The redirect URI must match exactly between:
- Your
config.jsonfile - Your GitHub OAuth App callback URL
Common issues:
- Using
https://instead ofhttp://for localhost - Port number mismatch
- Path mismatch (
/auth_flowvs/auth_flow/) - Using a production OAuth App with a production callback URL for local development
Solution: Create a separate OAuth App specifically for local development with http://localhost:3000/auth_flow as the callback URL.
import urllib.request
import json
url = "https://api.github.com/user"
access_token = "your-access-token"
req = urllib.request.Request(
url,
headers={
'Authorization': f'Bearer {access_token}',
'Accept': 'application/vnd.github+json',
'User-Agent': 'Your-App-Name'
}
)
with urllib.request.urlopen(req) as response:
data = json.loads(response.read().decode('utf-8'))
print(json.dumps(data, indent=2))url = "https://api.github.com/user/repos?per_page=10&sort=updated"
# Same headers as above- No Subdomain: GitHub doesn't use subdomains like Zendesk
- Form-Encoded Token Exchange: GitHub uses
application/x-www-form-urlencodedinstead of JSON - API Base URL: Uses
https://api.github.cominstead of subdomain-based URLs - Scope Format: Space-separated scopes in authorization URL
- No Refresh Tokens: GitHub tokens don't expire unless revoked