Using Deno KV OAuth
⚠️ Please note that this functionality relies on Deno KV which is currently marked as experimental and is subject to change. It is only available when using the
--unstable
flag.
⚠️ Please note that Deno KV OAuth is still in beta and is subject to change. See the documentation for further details.
Getting Started with the Official Fresh Plugin
Note: The minimum required version for plugins in Fresh is 1.3.0
If you’re not performing anything special in the sign-in, sign-out and callback
handlers, you can add the Fresh plugin to your project. This automatically
handles GET /oauth/signin
, GET /oauth/callback
and GET /oauth/signout
routes.
Create your OAuth 2.0 application for your given provider.
Create your pre-configured or custom OAuth 2.0 client instance and configure Fresh to use the plugin.
// main.ts import { start } from "$fresh/server.ts"; import kvOAuthPlugin from "$fresh/plugins/kv_oauth.ts"; import { createGitHubOAuth2Client } from "https://deno.land/x/deno_kv_oauth@$VERSION/mod.ts"; import manifest from "./fresh.gen.ts"; await start(manifest, { plugins: [ kvOAuthPlugin(createGitHubOAuth2Client()), ], });
⚠️ While Deno KV is still experimental you need to add the
--unstable
option to thestart
task in thedeno.json
file."start": "deno run -A --watch=static/,routes/ --unstable dev.ts",
Start your project with the necessary environment variables.
GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=xxx deno task start
If you require more advanced setups, you can create your own plugin. For more information, see:
- The source code for
kvOAuthPlugin()
- The Plugin documentation for Fresh
- The Fresh + Deno KV OAuth demo which uses the Fresh plugin
- Deno SaaSKit’s custom plugin implementation
Getting Started
This example uses GitHub as the OAuth 2.0 provider. However there is a suite of pre-configured providers available.
Register a new GitHub OAuth application, if you haven’t already.
Create your pre-configured OAuth client instance. For reusability the instance is stored in
utils/oauth2_client.ts
.utils/oauth2_client.tsimport { createGitHubOAuth2Client } from "https://deno.land/x/deno_kv_oauth@v0.2.4/mod.ts"; export const oauth2Client = createGitHubOAuth2Client();
Using the OAuth 2.0 client instance, insert the authentication flow functions into your authentication routes. In this example, there are dedicated handler routes at
routes/signin.ts
,routes/signout.ts
androutes/callback.ts
. Please ensure that thecallback
handler matches the authorization callback URL in the configured OAuth application.routes/signin.tsimport { Handlers } from "$fresh/server.ts"; import { signIn } from "https://deno.land/x/deno_kv_oauth@v0.2.4/mod.ts"; import { oauth2Client } from "../utils/oauth2_client.ts"; export const handler: Handlers = { async GET(req) { return await signIn(req, oauth2Client); }, };
routes/signout.tsimport { Handlers } from "$fresh/server.ts"; import { signOut } from "https://deno.land/x/deno_kv_oauth@v0.2.4/mod.ts"; export const handler: Handlers = { async GET(req) { return await signOut(req); }, };
routes/callback.tsimport { Handlers } from "$fresh/server.ts"; import { handleCallback } from "https://deno.land/x/deno_kv_oauth@v0.2.4/mod.ts"; import { oauth2Client } from "../utils/oauth2_client.ts"; export const handler: Handlers = { async GET(req) { // Return object also includes `accessToken` and `sessionId` properties. const { response } = await handleCallback(req, oauth2Client); return response; }, };
Use Deno KV OAuth’s helper functions where needed.
routes/index.tsximport { Handlers, PageProps } from "$fresh/server.ts"; import { getSessionAccessToken, getSessionId, } from "https://deno.land/x/deno_kv_oauth@v0.2.4/mod.ts"; import { oauth2Client } from "../utils/oauth2_client.ts"; interface User { login: string; name: string; avatar_url: string; } export const handler: Handlers<User | null> = { async GET(req, ctx) { const sessionId = await getSessionId(req); if (!sessionId) { return ctx.render(null); } const accessToken = await getSessionAccessToken(oauth2Client, sessionId); const response = await fetch("https://api.github.com/user", { headers: { authorization: `bearer ${accessToken}`, }, }); const user: User = await response.json(); return ctx.render(user); }, }; export default function Page({ data }: PageProps<User | null>) { if (!data) { return <a href="/signin">Sign In</a>; } return ( <div> <img src={data.avatar_url} width={64} height={64} /> <h1>{data.name}</h1> <p>{data.login}</p> <a href="/signout">Sign Out</a> </div> ); }
⚠️ While Deno KV is still experimental you need to add the
--unstable
option to thestart
task in thedeno.json
file."start": "deno run -A --watch=static/,routes/ --unstable dev.ts",
Start your project with the necessary environment variables.
GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=xxx deno task start
More on Deno KV OAuth
Follow the links to read more about:
- Using a provider from the list of pre-configured providers
- Configuring a custom OAuth 2.0 client
- Setting the mandatory environment variables
- Exploring a live demo