Deno KV OAuth (Beta)
Features
- Uses Deno KV for persistent session storage.
- Uses oauth2_client for OAuth workflows.
- Automatically handles the authorization code flow with Proof Key for Code Exchange (PKCE) and client redirection.
- Provides pre-defined OAuth configurations for popular providers.
- Works locally and in the cloud, including Deno Deploy.
- Based on the Web API's
Request
andResponse
interfaces. - Works with Fresh,
Deno.serve()
and Oak and other web frameworks. - Supports custom session cookie options
Documentation
Check out the full documentation and API reference here.
How-to
Get Started with a Pre-Defined OAuth Configuration
See here for the list of OAuth providers with pre-defined configurations.
-
Create your OAuth application for your given provider.
-
Create your web server using Deno KV OAuth's request handlers, helpers and pre-defined OAuth configuration.
// server.ts import { createGitHubOAuthConfig, getSessionId, handleCallback, signIn, signOut, } from "https://deno.land/x/deno_kv_oauth@$VERSION/mod.ts"; const oauthConfig = createGitHubOAuthConfig(); async function handler(request: Request) { const { pathname } = new URL(request.url); switch (pathname) { case "/oauth/signin": return await signIn(request, oauthConfig); case "/oauth/callback": const { response } = await handleCallback(request, oauthConfig); return response; case "/oauth/signout": return await signOut(request); case "/protected-route": return await getSessionId(request) === undefined ? new Response("Unauthorized", { status: 401 }) : new Response("You are allowed"); default: return new Response(null, { status: 404 }); } } Deno.serve(handler);
-
Start your server with the necessary environment variables.
GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=xxx deno run --unstable --allow-env --allow-net server.ts
Check out a full implementation in the demo source code which runs https://kv-oauth.deno.dev.
Get Started with a Custom OAuth Configuration
-
Create your OAuth application for your given provider.
-
Create your web server using Deno KV OAuth's request handlers and helpers, and custom OAuth configuration.
// server.ts import { getRequiredEnv, getSessionId, handleCallback, type OAuth2ClientConfig, signIn, signOut, } from "https://deno.land/x/deno_kv_oauth@$VERSION/mod.ts"; const oauthConfig: OAuth2ClientConfig = { clientId: getRequiredEnv("CUSTOM_CLIENT_ID"), clientSecret: getRequiredEnv("CUSTOM_CLIENT_SECRET"), authorizationEndpointUri: "https://custom.com/oauth/authorize", tokenUri: "https://custom.com/oauth/token", redirectUri: "https://my-site.com/another-dir/callback", }; async function handler(request: Request) { const { pathname } = new URL(request.url); switch (pathname) { case "/oauth/signin": return await signIn(request, oauthConfig); case "/another-dir/callback": const { response } = await handleCallback(request, oauthConfig); return response; case "/oauth/signout": return await signOut(request); case "/protected-route": return await getSessionId(request) === undefined ? new Response("Unauthorized", { status: 401 }) : new Response("You are allowed"); default: return new Response(null, { status: 404 }); } } Deno.serve(handler);
-
Start your server with the necessary environment variables.
CUSTOM_CLIENT_ID=xxx CUSTOM_CLIENT_SECRET=xxx deno run --unstable --allow-env --allow-net server.ts
Get Started with Cookie Options
This is required for OAuth solutions that span more than one sub-domain.
-
Create your OAuth application for your given provider.
-
Create your web server using Deno KV OAuth's helpers factory function with cookie options defined.
// server.ts import { createGitHubOAuthConfig, createHelpers, } from "https://deno.land/x/deno_kv_oauth@$VERSION/mod.ts"; const { signIn, handleCallback, signOut, getSessionId, } = createHelpers(createGitHubOAuthConfig(), { cookieOptions: { name: "__Secure-triple-choc", domain: "news.site", }, }); async function handler(request: Request) { const { pathname } = new URL(request.url); switch (pathname) { case "/oauth/signin": return await signIn(request); case "/oauth/callback": const { response } = await handleCallback(request); return response; case "/oauth/signout": return await signOut(request); case "/protected-route": return await getSessionId(request) === undefined ? new Response("Unauthorized", { status: 401 }) : new Response("You are allowed"); default: return new Response(null, { status: 404 }); } } Deno.serve(handler);
-
Start your server with the necessary environment variables.
GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=xxx deno run --unstable --allow-env --allow-net server.ts
Fresh
Get Started with-
Create your OAuth application for your given provider.
-
Create your OAuth configuration and Fresh plugin.
// plugins/kv_oauth.ts import { createGitHubOAuthConfig, createHelpers, } from "https://deno.land/x/deno_kv_oauth@$VERSION/mod.ts"; import type { Plugin } from "$fresh/server.ts"; const { signIn, handleCallback, signOut, getSessionId } = createHelpers( createGitHubOAuthConfig(), ); export default { name: "kv-oauth", routes: [ { path: "/signin", async handler(req) { return await signIn(req); }, }, { path: "/callback", async handler(req) { // Return object also includes `accessToken` and `sessionId` properties. const { response } = await handleCallback(req); return response; }, }, { path: "/signout", async handler(req) { return await signOut(req); }, }, { path: "/protected", async handler(req) { return await getSessionId(req) === undefined ? new Response("Unauthorized", { status: 401 }) : new Response("You are allowed"); }, }, ], } as Plugin;
-
Start your Fresh server with the necessary environment variables.
GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=xxx deno task start
Run the Demo Locally
The demo uses GitHub as the OAuth provider. You can change the OAuth
configuration by setting the oauthConfig
constant as mentioned above.
-
Create your OAuth application for your given provider.
-
Start the demo with the necessary environment variables.
TWITTER_CLIENT_ID=xxx TWITTER_CLIENT_SECRET=xxx deno task demo
Concepts
Redirects after Sign-In and Sign-Out
The URL that the client is redirected to upon successful sign-in or sign-out is determined by the request made to the sign-in or sign-out endpoint. This value is set in the following order of precedence:
- The value of the
success_url
URL parameter of the request URL, if defined. E.g. a request tohttp://example.com/signin?success_url=/success
redirects the client to/success
after successful sign-in. - The value of the
Referer
header, if of the same origin as the request. E.g. a request tohttp://example.com/signin
withReferer
headerhttp://example.com/about
redirects the client tohttp://example.com/about
after successful sign-in. - The root path, "/". E.g. a request to
http://example.com/signin
without theReferer
header redirects the client tohttp://example.com
after successful sign-in.
Pre-Defined OAuth Configurations
Providers
The following providers have pre-defined OAuth configurations:
Environment Variables
These must be set when starting a server with a pre-defined OAuth configuration.
Replace the PROVIDER
prefix with your given OAuth provider's name when
starting your server. E.g. DISCORD
, GOOGLE
, or SLACK
.
PROVIDER_CLIENT_ID
- Client ID of a given OAuth application.PROVIDER_CLIENT_SECRET
- Client secret of a given OAuth application.PROVIDER_DOMAIN
(optional) - Server domain of a given OAuth application. Only required for Okta and Auth0.
Note: reading environment variables requires the
--allow-env[=<VARIABLE_NAME>...]
permission flag. See the manual for further details.
Built with Deno KV OAuth
- Deno KV OAuth live demo
- Deno SaaSKit - A modern SaaS template built on Fresh and uses a custom Deno KV OAuth plugin.
- KV SketchBook - Dead simple sketchbook app.
- Fresh + Deno KV OAuth demo - A demo of Deno KV OAuth working in the Fresh web framework.
- Oak + Deno KV OAuth demo - A demo of Deno KV OAuth working in the Oak web framework.
- Ultra + Deno KV OAuth demo - A demo of Deno KV OAuth working in the Ultra web framework.
- Hono + Deno KV OAuth demo - A demo of Deno KV OAuth working in the Hono web framework.
- Cheetah + Deno KV OAuth demo - A demo of Deno KV OAuth working in the Cheetah web framework.
- Paquet - A web app shop
- Fastro + Deno KV OAuth live demo - A simple, reusable fastro module that implements Deno KV.
Do you have a project powered by Deno KV OAuth that you'd like to share? Feel free to let us know in a new issue.
Known Issues
- Twitch is not supported as an OAuth provider because it does not support PKCE. See #79 and this post for more information.
Contributing Guide
Check out the contributing guide here.
Security Policy
Check out the security policy here.