Cloudflare Worker for GitHub Gist OAuth
November 28, 2024 ยท View on GitHub
human (Nov 28, 2024, 07:06 AM)
Write a Cloudflare worker that implements an oauth flow with GitHub to get a token scoped for gist read and write only
Landing on the worker page redirects to GitHub for the oauth - GitHub sends back to the same page, which then outputs a script block that sets the access key in localstorage
assistant (Nov 28, 2024, 07:06 AM)
I'll help you create a Cloudflare Worker that implements the GitHub OAuth flow for gist permissions.
Cloudflare Worker for GitHub OAuth
export default {
async fetch(request, env) {
const url = new URL(request.url);
const clientId = env.GITHUB_CLIENT_ID;
const clientSecret = env.GITHUB_CLIENT_SECRET;
const redirectUri = url.origin;
// If we have a code, exchange it for an access token
if (url.searchParams.has('code')) {
const code = url.searchParams.get('code');
// Exchange the code for an access token
const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
client_id: clientId,
client_secret: clientSecret,
code: code,
redirect_uri: redirectUri
})
});
const tokenData = await tokenResponse.json();
// Return HTML that stores the token and closes the window
return new Response(`
<!DOCTYPE html>
<html>
<head>
<title>GitHub OAuth Success</title>
</head>
<body>
<script>
localStorage.setItem('github_token', '${tokenData.access_token}');
document.body.innerHTML = 'Authentication successful! You can close this window.';
</script>
</body>
</html>
`, {
headers: {
'Content-Type': 'text/html'
}
});
}
// If no code, redirect to GitHub OAuth
const githubAuthUrl = new URL('https://github.com/login/oauth/authorize');
githubAuthUrl.searchParams.set('client_id', clientId);
githubAuthUrl.searchParams.set('redirect_uri', redirectUri);
githubAuthUrl.searchParams.set('scope', 'gist');
githubAuthUrl.searchParams.set('state', crypto.randomUUID());
return Response.redirect(githubAuthUrl.toString(), 302);
}
};
To use this worker, you'll need to:
-
Create a GitHub OAuth application at https://github.com/settings/developers
- Set the homepage URL to your worker's URL
- Set the callback URL to your worker's URL
-
Set up two environment variables in your worker:
GITHUB_CLIENT_ID: Your OAuth app's client IDGITHUB_CLIENT_SECRET: Your OAuth app's client secret
The flow works like this:
- User visits the worker URL
- They're redirected to GitHub's OAuth page
- After authorizing, GitHub redirects back to your worker with a code
- The worker exchanges the code for an access token
- The token is stored in localStorage with key 'github_token'
The token will be scoped only to gist read/write permissions since we specifically request the 'gist' scope.
Would you like me to add any additional features like:
- Error handling
- CSRF protection
- Token validation
- Specific response types for different scenarios?