This is a companion repository for the blog post at Apiumhub :: Tech blog.
In the blog post, we go though the code that OAuth-s a user and uses a Google API for that user. We'll be developing this app that lists, based on a query, the files in that user's Google Drive. Like so:
Generated with sequencediagram.org
title Sequence of requests
Client->Cloudflare Worker: GET / note left of Cloudflare Worker: The client is unauthenticated Cloudflare Worker-->Client: Redirect to Google Sign in Client->Google API: Ask for permission Google API-->Client: Prompt to sign in Client->Google API: Grant permissions activate Google API note left of Google API: Google now\nhas a session\nfor the user Google API-->Client: Go back to the Cloudflare Worker with atokenClient->Cloudflare Worker: GET /auth with acodeCloudflare Worker->Google API: Exchangecodefor atokenGoogle API-->Cloudflare Worker: a token activate Cloudflare Worker note left of Cloudflare Worker: An auth is stored in the KV with the code Cloudflare Worker-->Client: Go back to the original request with the auth cookie Client->Cloudflare Worker: GET / note left of Cloudflare Worker: Now the client is autenticated Cloudflare Worker->Google API: Get files Google API-->Cloudflare Worker: A list of files Cloudflare Worker-->Client: An HTML with a list of files expandable− logout Client->Cloudflare Worker: GET /logout Cloudflare Worker->Google API: Logout deactivate Google API Google API-->Cloudflare Worker: OK deactivate Cloudflare Worker Cloudflare Worker-->Client: OK end
A more detail explanation of how Google Sign in should behave can be found in Google's docs: Using OAuth 2.0 for Web Server Applications.
- wrangler 1.17 or newer.
- A Cloudflare account.
- A Google Services account
- With the API you wish to consume enabled. e.g: https://console.developers.google.com/apis/api/drive.googleapis.com/overview
- A Google OAuth Client ID and Secret, from the Credentials > + Create credentials > Oauh client ID. _Note: "Authorized redirect URIs" should have your cloudflare worker url with
/authat the end, and optionalyhttp://127.0.0.1:8787/authto work locally.
- Clone this template:
wrangler generate [a name] https://github.com/jazcarate/cloudflare-worker-google-oauth. - Update the worker's secrets with the ones generated by creating the
Credentialsin the Google Service Account:wrangler secret put CLIENT_ID [your client id]wrangler secret put CLIENT_SECRET [your client secret]
- Create a
KVnamespace:wrangler kv:namespace create "authTokens"and update thewrangler.tomlaccordingly.
If you would like to use this setups as a starting point to develop interesting things; I recommend trying out one (or all!) of this improvements:
- Create a middleware pattern to deaal with authenticated and unauthenticated endpoints
- Serve static content, either with Cloudflare Sites, or reading local files in a Worker. A default path could be implemented to serve files in
public/folder. - Improve the rendered HTML with a template library, or roll up your own!
- Use another Google API from the list.
Throughout this project there are two somewhat similar, but distincts concepts:
- Google's
code: Is a one time code that is quickly exchanged with Google for atoken👇. token: Is the authentication method for Google.auth: Is the authentication method for this Worker.
The app deals with both, in very different ways; and it is the KV that provides a one way transformation between auth to token.
If you think that you can improve the code, or the explanation; feel free to drop a pull request or a comment; but please keep in mind that the purpose of this is educational.
Once the requirements are fulfilled, simply run npm run dev.
The server will default to running at 127.0.0.1:8787.
Rn npm test for jest tests.
Run npm run publish to lint, build and publish to your Cloudflare Worker!
Some 🪄 wizardry was implemented to know if the code was running locally (with wrangler dev) or in the cloud; as wrangler dev reweites the request.url to always match the environment.
